# Welcome to LOCI

## LOCI catches what coding agents miss.

LOCI reads BIN files. Sees how code runs, beyond source or patterns.\
She shares her findings with agents at Plan, Write, Review, PR, and Merge.\
Ground truth. Every stage of the loop.

Coding agents write code. LOCI thinks ahead.

Learned from real workloads and platform traces — not source code alone.

•Less babysitting&#x20;

• Fewer regressions&#x20;

• Higher first-pass accuracy

Powered by AI Physics — trained on real workloads and platform traces

***

{% hint style="info" %}
Need help? Reach out at <support@auroralabs.com>

Let’s automate binary analysis — at scale, with AI.
{% endhint %}


# Introduction

### What is LOCI?

LOCI bridges this gap by modeling compiled binaries with real-world execution data, enabling it to:

* Predict performance impacts
* Detect degradations across software versions
* Identify power-hungry functions
* Optimize resource efficiency
* Provide test coverage references
* Enhance testing & validation

### The LOCI Ecosystem

LOCI is made up of several components that work together across your development and CI/CD workflow:

* **LOCI Inspector** — The execution-aware code dashboard. Visualize function-level performance metrics, explore call graphs, and compare versions to catch regressions before they reach production.
* **LOCI Insights** — Deep-dive report view for breaking down metrics by function and module. Sort, filter, and track trends over time.
* **GitHub Integration** — Automates binary analysis inside GitHub CI/CD. Uploads binaries on every PR and posts performance insights directly as PR comments.
* **Azure DevOps Integration** — The Azure Pipelines counterpart. Connects your pipeline to LOCI for upload-based analysis and PR-thread feedback.
* **LOCI CLI** — Terminal interface for manually uploading binaries and checking analysis progress without leaving your shell.
* **API / CI Quick Start** — HTTP-based access for uploading binaries, polling for results, and retrieving reports programmatically.
* **Self-Hosted Deployment** — Run LOCI inside your own AWS account using `loci-box` and the bootstrapper Docker image.

### Supported Uploads:

* Upload ELF/binaries as a ZIP or TAR archive.
* Files must include symbol information for accurate results.
* ELF/binaries can be compiled from C, C++, or Go Lang.

### Supported Architectures:

* ARMv8 64-bit (Timing reference based on ARM Cortex-A53 processor)
* Aurix TriCore processors (Timing reference based on Aurix TC399 processor)
* ARM Cortex-M4 (Timing reference based on ARM Cortex-M4 processor)


# LOCI Product Platform - Architecture of the Customer-Facing Ecosystem

### How is LOCI delivered to users?

The CI/CD surfaces a customer wires into their own pipelines, the command-line client that carries every programmatic interaction, the central backend that holds the business logic and the source-control integrations, the web dashboard where analyses are explored, and the AI agent layer that turns analysis results into written summaries and conversation.&#x20;

Together these are the product around LOCI's analysis engine — how binaries get in, and how insight gets back to the engineer.

What happens *inside* the analysis — static analysis, model inference, and insight generation — is the binary processing pipeline and is described in the separate pipeline document; here it is a downstream boundary. The customer contract of the GitHub CI/CD surface is described in depth in the CI/CD integration document; here the surfaces appear at ecosystem level. The internals of the AI agent layer are described in the separate agent document; here it appears at the interface level.

***

### System overview

LOCI is delivered as a hosted, multi-tenant platform, and a customer reaches it in two ways: through their **development workflow** — a CI/CD integration builds and uploads the compiled binaries on every change, and the results return to the pull request as a comment and a performance check — and through the **web dashboard**, where binaries ready for processing are uploaded manually, projects and versions are managed, and results are explored interactively. Both paths converge on the platform backend, which owns the business objects (companies, users, projects, versions, analyses), hands uploaded binaries to the processing pipeline, stores and serves the resulting insights, and brokers the AI agent layer. The unit of work throughout is a **version** — a named upload of a project's compiled binaries — and on a pull request the platform's central object is the comparison of the change's version against its base.

*The ecosystem. Both customer paths converge on the platform backend; the numbered flows are explained in the panel beside the diagram. The pipeline's stages are shown for orientation only — they are the pipeline document's subject.*

<figure><img src="/files/8aKdpd55fxtv0alOKrs0" alt=""><figcaption></figcaption></figure>


# Which path is right for you?

* Start with the Claude Plugin if your team uses Claude Code for active development - install in 2 commands, no pipeline changes required.
* Start with the GitHub Action if you want LOCI on every PR without changing how developers work - wire once at the CI level.
* Use the Azure Extension if your team is on Azure DevOps - requires additional admin setup (service hook, bot user, PAT). Allow 30 minutes for first-time configuration.


# LOCI Plugin for AI Coding Assistants

## AI Writes Code. LOCI Gates It.

LOCI is a quality-gate agent for Claude Code that models regressions, power, latency, and control-flow safety directly from your compiled binary, from plan to merge. It requires no running code, no instrumentation, and no code changes: every result is grounded in real execution data recovered from the binary itself.

***

### What LOCI does

LOCI connects Claude Code to LCLM (Large Code Language Model), a model trained on billions of assembly blocks and real hardware traces from IoT, networking, and safety-critical systems — not a general-purpose model wrapped around your code. Because analysis happens at the binary level, LOCI can answer questions about timing, energy, memory, and control flow that source-level tools can't: the actual compiled output, not an approximation of it.

***

### Prerequisites

| Requirement                           | Version | Required for                                                                                                                           |
| ------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| [Claude Code](https://claude.ai/code) | latest  | Everything                                                                                                                             |
| Python                                | 3.12+   | The `loci` CLI (local ELF/ build analysis)                                                                                             |
| [uv](https://docs.astral.sh/uv/)      | any     | Installs the `loci` CLI as a tool. Install this yourself — the plugin checks for it and gives you the install command if it's missing. |
| jq                                    | any     | Session hooks. Install this yourself - the plugin checks for it and gives you the install command if it's missing.                     |

**Cross-compiler depends on the** project you work with.

Skills that work without a cross-compiler or backend network access: `stack-depth`, `memory-report`, `control-flow`.

***

### Install

Install the plugin from inside Claude Code:

`/plugin marketplace add` [`https://github.com/auroralabs-loci/loci-claude`](https://github.com/auroralabs-loci/loci-claude)

`/plugin install loci@loci`

`/reload-plugins`

`/loci:setup`

\
There is no separate CLI download step. The loci command-line tool is installed automatically in the background the first time a Claude Code session starts, using uv. If uv or jq aren't already on your system, Claude will tell you the install command to run.

***

### Authentication

Timing and energy analysis reach the LOCI backend and require a signed-in session.

1. Run `! loci login` from inside Claude Code (or `loci login` in your terminal).
2. Confirm it worked with `loci auth status` - it should show `signed_in`.

* `stack-depth`, `memory-report`, and `control-flow` run fully offline.&#x20;
* `exec-trace`, `loci-preflight`, and `loci-post-edit` require a signed-in session because they call the LOCI backend.

***

### Quick Start

Once installed, try these in any C/C++/Rust project with compiled binaries:

1. **Timing & energy** — ask: "What's the execution cost of main()?"
2. **Memory budget** — ask: "How much ROM/RAM does my build use?"
3. **Stack safety** — ask: "Is my stack safe for TaskMain?"
4. **Control-flow safety** — ask: "What does the call graph for process\_data() look like?"

Two skills also run automatically, with no invocation needed:

* `loci-preflight` fires during `/plan` mode — analyzes callees at the binary level before code is written.
* `loci-post-edit` fires after every edit to C/C++/Rust source — diffs the binary and returns a regression verdict.

***

### Skills Reference

<table data-header-hidden><thead><tr><th width="141"></th><th width="216"></th><th width="93"></th><th></th></tr></thead><tbody><tr><td>Skill</td><td>Trigger</td><td>Sign-in required</td><td>What it does</td></tr><tr><td>loci-preflight</td><td>Automatic, in <code>/plan</code> mode</td><td>Yes</td><td>Audits the plan at binary level before code is written — timing, energy, and control-flow-graph impact.</td></tr><tr><td>loci-post-edit</td><td>Automatic, after edits to C/C++/Rust</td><td>Yes</td><td>Diffs pre/post compiled artifacts and returns a regression verdict on timing, energy, and control flow.</td></tr><tr><td>exec-trace</td><td>User-invoked</td><td>Yes</td><td>Function-level timing and energy from real-time hardware traces, powered by LCLM.</td></tr><tr><td>stack-depth</td><td>User-invoked</td><td>Yes</td><td>Worst-case stack depth via call-graph traversal and per-function frame sizes.</td></tr><tr><td>memory-report</td><td>User-invoked</td><td>Yes</td><td>ROM/RAM section breakdown and top consumers from compiled ELF binaries.</td></tr><tr><td>control-flow</td><td>User-invoked</td><td>Yes</td><td>Annotated control-flow graphs, optimized for LLM analysis.</td></tr><tr><td>trends</td><td>User-invoked</td><td>Yes</td><td>Per-function measurement history and optimization progress on the current branch.</td></tr><tr><td>help</td><td><code>/help</code></td><td>No</td><td>Confirms LOCI is loaded and lists available skills.</td></tr><tr><td>setup</td><td><code>/loci:setup</code>, or automatically on CLI-missing errors</td><td>No</td><td>Installs, repairs, or verifies the <code>loci</code> CLI. Safe to re-run at any time.</td></tr><tr><td>bug-report</td><td><code>/bug-report</code></td><td>No</td><td>Generates a full diagnostic report when something isn't working.</td></tr></tbody></table>

***

### Automatic Hooks

The plugin registers four hooks that run without user action:

<table data-header-hidden data-search="true"><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td>Hook</td><td>Trigger</td><td>What it does</td></tr><tr><td><code>SessionStart</code></td><td>Session startup</td><td>Detects your project's build system, compiler, and target architecture; installs the <code>loci</code> CLI in the background if it's missing; and injects session context (auto-run rules, tool policy, response tone) for Claude to use. Never blocks session startup, even if detection or install fails.</td></tr><tr><td><code>PreToolUse</code></td><td>Before Edit, Write, or MultiEdit</td><td>Snapshots the current compiled <code>.o</code> for later delta analysis and runs a static call-graph pre-scan of the incoming code (before it's written to disk), surfacing any findings as context. Advisory only — always exits 0, never blocks the edit.</td></tr><tr><td><code>PostToolUse</code></td><td>After Edit, Write, or MultiEdit</td><td>Checks whether the change could alter a compiled function's body and, if so, injects a reminder instructing Claude to run the <code>loci-post-edit</code> skill immediately. Advisory only — always exits 0, never blocks.</td></tr><tr><td><code>Stop</code></td><td>End of session</td><td>If the <code>loci</code> CLI is present, flushes any pending analysis results to your account (<code>loci stats flush-impacts</code>).</td></tr></tbody></table>

***

### Troubleshooting

`loci` **CLI not found**:

1. Check it's on PATH: `command -v loci` and `loci --version`.
2. If it's missing, the background install may still be running or may have failed. Run `/loci:setup` to reinstall and verify — it's safe to re-run — or `loci doctor` once the CLI is present.
3. Confirm `uv` is installed (`command -v uv`); the plugin needs it to install the CLI.

**A skill reports** `auth_required`:

1. Run `! loci login` in your terminal, then retry.
2. Confirm `loci auth status` shows `signed_in`.<br>

**Auto-skills didn't fire**:

* `loci-preflight` only runs in `/plan` mode — confirm you're planning new logic, not just asking a question.
* `loci-post-edit` only runs after edits to C/C++/Rust source files.
* Both compile the source themselves — they don't need a pre-built binary. They do require a supported LOCI target and a working cross-compiler for it on PATH, plus a valid session context from startup. If the compiler is missing, restore it (or point LOCI at it) and re-run.<br>

**On-demand skills didn't respond**:

* Type `/help` to confirm LOCI is loaded and see the full skill list.
* Restart Claude Code from inside your project directory if the build environment wasn't detected at session start.
* Check that a cross-compiler is installed and on your PATH (see the table above).

**Nothing seems to work**:

Run `/bug-report` to generate a full diagnostic report.

***

### LOCI Portal

Every analysis run from Claude Code is logged and visualized automatically at the LOCI Portal (app.auroralabs.com), no extra configuration needed. The Portal is where you view session history, binary analysis results, PR review status, and team/quota settings.

***

### Account Plans

LOCI is available on a free tier with limited daily interactions. Paid tiers raise or remove that limit and unlock additional capabilities...&#x20;

For current plans and pricing, see [auroralabs.com/pricing](https://www.auroralabs.com/pricing).

***

### Support

* Email: <loci@auroralabs.com>
* Plugin issues: [github.com/auroralabs-loci/loci-claude/issues](https://github.com/auroralabs-loci/loci-claude/issues)

***

### Reference

* Quick Start (web): `auroralabs.com/product#quick-start`
* Talk to us: `auroralabs.com/contact`
* LOCI install endpoint: `https://loci.auroralabs.com/install.sh`


# How LOCI fits your loop.

One signal layer across four stages.&#x20;

Your coding agent calls LOCI at Plan, Write, PR and Merge.&#x20;

You see verdict, evidence, autonomy.

Works with Claude Code, Cursor, Copilot, and your agentic flow.


# LOCI Claude plugin


# Installing the LOCI Claude Plugin

### Prerequisites

| Requirement                           | Version                | Required for                                                                                                                           |
| ------------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| [Claude Code](https://claude.ai/code) | latest                 | Everything                                                                                                                             |
| Python                                | 3.12+                  | The `loci` CLI (local ELF/build analysis)                                                                                              |
| [uv](https://docs.astral.sh/uv/)      | any                    | Installs the `loci` CLI as a tool. Install this yourself — the plugin checks for it and gives you the install command if it's missing. |
| jq                                    | any                    | Session hooks. Install this yourself — the plugin checks for it and gives you the install command if it's missing.                     |
| Compiled binaries                     | `.elf` / `.o` / `.axf` | All skills                                                                                                                             |

**Cross-compiler** (one required, depending on your target):

| LOCI Target | CPU / Silicon          | Default cross-compiler  |
| ----------- | ---------------------- | ----------------------- |
| `armv6-m`   | ARM Cortex-M0+         | `arm-none-eabi-gcc`     |
| `armv7e-m`  | ARM Cortex-M4          | `arm-none-eabi-gcc`     |
| `aarch64`   | ARM Cortex-A (A53)     | `aarch64-linux-gnu-gcc` |
| `tc399`     | Infineon TriCore TC3xx | `tricore-elf-gcc`       |

These are the only 4 architectures LOCI's analysis backend supports. Rust sources are also supported (via `rustc` — LOCI needs the matching `rustup target add` triple for your LOCI target); a project can mix C/C++ and Rust.

Inside Claude Code:

### Step 1 — Add Marketplace

```
/plugin marketplace add auroralabs-loci/loci-claude
```

### Step 2 - Install plugin

```
/plugin install loci@loci
```

There is no separate CLI download step. The `loci` command-line tool installs itself automatically in the background the first time a Claude Code session starts, using `uv`.

You can also do this through the interactive menu instead of typing the commands directly: run `/plugin`, then go to **Discover → LOCI** and **Install → LOCI**. Both paths do the same thing.

### Step 3 — Reload plugin

```
/reload-plugins
```

**Required.** Claude Code needs this to pick up the newly installed plugin's hooks and skills in your current session — without it, LOCI won't be active yet even though the install succeeded.

### Step 4 — Run plugin

```
/loci:setup
```

**Required.** This installs the `loci` CLI (as a `uv` tool) and verifies your environment — compiler, architecture, and build system detection, plus the health checks covered in Troubleshooting. It's idempotent and safe to re-run any time; if `uv` or `jq` aren't already on your system, it tells you the exact install command for your OS instead of installing them for you (they need root/an interactive password prompt).

The plugin's `SessionStart` hook also attempts this install automatically in the background on every session start, but running `/loci:setup` explicitly is how you confirm it actually succeeded before relying on any skill.

### You're done

Once setup reports healthy, the plugin is ready to use. Next, sign in — then try any on-demand skill (e.g. ask "What's the execution cost of `main()`?") or just start editing C/C++/Rust source and `loci-post-edit` will run automatically.

### Next steps

* [Authenticating the LOCI Claude Plugin](/loci-plugin-for-ai-coding-assistants/loci-claude-plugin/authenticating-loci-claude-plugin) — sign in before using any analysis skill
* [Skills Reference](/loci-plugin-for-ai-coding-assistants/loci-claude-plugin/skills-reference-for-loci-claude-plugin) — what each skill does
* [Troubleshooting](/loci-plugin-for-ai-coding-assistants/loci-claude-plugin/troubleshooting) — if the install doesn't finish or a skill won't respond


# Authenticating LOCI  Claude Plugin

### Why sign-in is required

The `loci` CLI enforces sign-in on every command except five: `loci login`, `loci logout`, `loci auth status`, `loci doctor`, and an internal Stop-hook verb. Every other command — including ones that never touch the network, like `loci elf stack` — refuses to run if you're signed out.

In practice this means: **all 7 analysis skills require a signed-in session.**&#x20;

Only `/help`, `/loci:setup`, and `/bug-report` work signed out.

| Requires sign-in             | Doesn't require sign-in |
| ---------------------------- | ----------------------- |
| `loci-preflight` (automatic) | `/help`                 |
| `loci-post-edit` (automatic) | `/loci:setup`           |
| `/exec-trace`                | `/bug-report`           |
| `/stack-depth`               |                         |
| `/memory-report`             |                         |
| `/control-flow`              |                         |
| `/trends`                    |                         |

### Signing in

```
! loci login
```

(or `loci login` directly in a terminal). This opens your default browser to a one-time OAuth sign-in (PKCE flow). Free tier works on one repository, no credit card required.

Confirm it worked:

```
! loci auth status
```

Shows `signed_in` plus your session's expiry time.

### Where your session is stored

Your session token is stored in your OS's credential manager (keyring) when one is available. On hosts without a usable keyring (headless/SSH/WSL/Docker/CI), it falls back to a `0600`-permission file at `~/.loci/credentials.json`. `loci doctor` reports which backend is in use.

### Session expiry and re-authentication

Sessions expire after a period of inactivity. When that happens, the next analysis skill reports `auth_required` — run `! loci login` again and retry.

### Signing out

```
! loci logout
```

Removes your stored credential from both the keyring and the file fallback.

### Headless environments (no browser)

If Claude Code can't open your browser automatically, `loci login` prints the sign-in URL to the terminal instead — copy it into any browser to complete sign-in.

### Common issues

**A skill reports `auth_required`:**

1. Run `! loci login`, then retry the skill.
2. Confirm with `! loci auth status` that it now shows `signed_in`.

**A skill reports `quota_exceeded`:** this is different from `auth_required` — you're signed in, but you've hit your plan's daily limit. The error message includes the reset time. See Account Plans (or your current pricing page) to raise the limit.

### Related pages

* [Installing the Plugin](/loci-plugin-for-ai-coding-assistants/loci-claude-plugin/installing-the-loci-claude-plugin)
* [Skills Reference](/loci-plugin-for-ai-coding-assistants/loci-claude-plugin/skills-reference-for-loci-claude-plugin)
* [Troubleshooting](/loci-plugin-for-ai-coding-assistants/loci-claude-plugin/troubleshooting)


# Skills Reference for LOCI Claude Plugin

All skills need a signed-in session except `help`, `setup`, and `bug-report` — see [Authenticating](/loci-plugin-for-ai-coding-assistants/loci-claude-plugin/authenticating-loci-claude-plugin).

### Automatic — no command needed

#### loci-preflight

Runs automatically in `/plan` mode when you describe new logic. Audits the plan at the binary level — before any code is written — checking timing, energy, and control-flow impact of the callees your new code will invoke.

*Example:* you ask Claude to "add a retry mechanism to `uart_send`." Before writing code, LOCI checks the timing/energy/safety profile of the functions the retry logic will call, and returns one of three verdicts:

* **GOOD** — plan is safe to proceed
* **ADJUST PLAN** — a specific concern is flagged with a recommendation
* **STOP** — regression risk is high; the plan should be reworked

#### loci-post-edit

Runs automatically after every edit to a C/C++/Rust source file. Compiles the change, diffs the binary against the pre-edit version, and reports the timing/energy delta at the function level.

*Example output:*

```
uart_send
  Before:  1.24 µs   After:  1.31 µs   Δ +5.6%   ⚠ CAUTION
```

Regressions are caught at the binary level — a change that looks clean in the source diff can still alter execution behavior.

### On-demand — invoke with a slash command or a natural-language question

#### /exec-trace

Function-level timing and energy from real hardware traces (via LCLM).

*Ask:* "What's the execution cost of `motor_control_loop`?"

```
motor_control_loop
  Execution time:  3.82 µs  (std dev: 0.12 µs)
  Energy:          0.0041 Ws
  Hottest block:   pid_update — 61% of total cycles
```

Low standard deviation means strong empirical backing from LCLM's training data; high standard deviation means the assembly pattern is underrepresented, and the estimate should be treated with more caution.

#### /stack-depth

Worst-case stack depth via call-graph traversal, with a pass/fail verdict against a budget.

*Ask:* "Is the stack safe for `TaskMain` with a 2048-byte budget?"

```
Stack Depth: TaskMain
  Worst-case depth:   312 bytes
  Worst-case path:    TaskMain → process_data → decode → crypto_verify
  Budget:             2048 bytes  (15.2% used)
  Verdict: ✅ PASS 15.2%
```

Auto-detects RTOS task entry points from `xTaskCreate`, `Task_construct`, `osThreadNew`, and `FreeRTOSConfig.h`.

#### /memory-report

ROM/RAM section breakdown and top consumers from a compiled ELF binary — no runtime, no instrumentation.

*Ask:* "How much ROM/RAM does my build use?"

Reports section-by-section size (`.text`, `.rodata`, `.data`, `.bss`), top ROM/RAM consumers by function/variable, and — if you provide a linker map file — usage against your memory region budgets.

#### /control-flow

Annotated control-flow graph for a function, extracted directly from the compiled binary.

*Ask:* "Show me the call graph for `process_data()`."

```
Control-Flow Analysis: process_data()
  Call graph:
    process_data()
      ├─ validate_header()        [direct]
      ├─ dispatch_handler()       [direct]
      │    └─ r3 → ??            [indirect · bl r3]  ⚠
      └─ finalize_output()        [direct]
  Findings:
    ⚠  dispatch_handler — indirect call via register (bl r3)
       Verify the dispatch table is bounds-checked before this path is reachable.
```

Indirect calls through registers are a finding class source review alone can't see.

#### /trends

Per-function measurement history on the current branch — timing, stack, and memory trends over time.

*Ask:* "Show me my optimization progress on this branch" or just `/trends`.

Shows a table of tracked functions with edits, first/latest measurement, and direction (improved / regressed / stable / baseline). Read-only — this skill never records new data itself.

### Utility — work signed out

#### /help

Shows your environment status (target architecture, compiler, build system, sign-in state, daily quota) and the full skill list, adapted to what's currently working.

#### /loci:setup

Installs, repairs, or verifies the `loci` CLI. Safe to re-run any time; also runs automatically if a skill hits a "CLI missing" error.

#### /bug-report

Generates a full forensic diagnostic report (environment snapshot, a 10-point health checklist, and root-cause reasoning) when something isn't working. Writes a timestamped `.md` file you can share or load into a new session.


# CLI Reference for LOCI Claude Plugin

This is the `loci` command — the analysis engine the plugin's skills call (PyPI package `loci-tools`). **This is not the same tool as the site's general "CLI" section** (that documents `loci_api`, a separate, older manual-upload tool with commands like `list-projects` and `upload`). If you're using the Claude Code plugin, this page is the one that applies.

### Installation

Installed automatically by the plugin at session start. To install or verify manually:

```
uv tool install loci-tools
loci --version
loci doctor
```

### Global behavior

Every `loci` command prints one self-describing JSON document to stdout: `{"ok": true, "data": {...}}` on success, `{"ok": false, "error": {"message": "...", "code": "..."}}` on failure. Diagnostic/progress logs go to stderr, never stdout. The `-f`/`--format` flag controls the envelope's serialization: `json` (default), `yaml`, `csv`, `tsv`, `md`, or `toon`.

**Login gate:** every command below requires a signed-in session *except* `login`, `logout`, `auth status`, and `doctor`. Two stable error codes to branch on: `auth_required` (exit 3 — not signed in / token expired) and `quota_exceeded` (exit 4 — plan limit reached).

### auth

| Command            | Flags                                                                   | Notes                                            |
| ------------------ | ----------------------------------------------------------------------- | ------------------------------------------------ |
| `loci login`       | `--auth-server URL`, `--scope SCOPE`, `--timeout SECONDS` (default 120) | Browser PKCE sign-in. Public (works signed out). |
| `loci logout`      | —                                                                       | Removes stored credential. Public.               |
| `loci auth status` | —                                                                       | Shows `signed_in`/expiry. Public.                |

### elf — local binary analysis (no model call)

All subcommands take `--arch` except `memmap`, which auto-detects from the ELF. `--arch` accepts the 4 canonical targets (`aarch64`, `armv7e-m`, `armv6-m`, `tc399`) plus common aliases (e.g. `cortex-m4`, `cortex-m0+`, `arm64`, `armv8-a`).

| Command            | Key flags                                                                                                                                                                                           | What it returns                                                                                                                            |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `loci elf asm`     | `--elf` (required), `--arch`, `--functions f1,f2`, `--out-dir`, `--blocks`                                                                                                                          | Assembly, control-flow graph, and timing CSV for named functions (or all, if omitted). Bulky output goes to files; envelope carries paths. |
| `loci elf cfg`     | `--elf` (required), `--arch`, `--functions`                                                                                                                                                         | Annotated control-flow graph, written to `control-flow.txt`.                                                                               |
| `loci elf symbols` | `--elf` (required), `--arch`, `--inline-threshold N` (default 200), `--payload-format`                                                                                                              | Symbol table — inline in the response when ≤ N symbols, else spilled to a file.                                                            |
| `loci elf diff`    | `--elf`, `--comparing-elf` (both required), `--arch`                                                                                                                                                | Which functions were added/modified/removed between two binaries.                                                                          |
| `loci elf stack`   | `--elf` or `--asm` (one required), `--arch`, `--entry-functions`, `--stack-budget BYTES`, `--threshold PCT` (default 50), `--max-recursion-depth` (default 1), `--unknown-callee-size` (default 64) | Worst-case stack depth via call-graph traversal; pass/fail verdict when `--stack-budget` is given.                                         |
| `loci elf memmap`  | `--elf` (required, **no `--arch`**), `--comparing-elf`, `--map-file`, `--top-n` (default 10), `--with-heap`, `--allocators-file`                                                                    | ROM/RAM section breakdown, top consumers, optional region budgets and heap-allocation analysis.                                            |
| `loci elf slice`   | `--elf` (required), `--arch`, `--output-types` (default `asm,symbols`), `--filter-functions`                                                                                                        | Lower-level extraction primitive underlying `asm`/`symbols` — asm, symbols, blocks, segments, callgraph, or elfinfo.                       |

### build — compile sources and track how they were built

| Command               | Key flags                                                                                                                                                                                         | What it does                                                                                                                                                                                    |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `loci build compile`  | `--source` (required), `--loci-target` (required; one of the 4 targets), `--context`, `--compiler-path`, `--project-root`, `--output`, `--meta-prev`, `--phase preflight\|post-edit`, `--verbose` | Compiles a C/C++/Rust source, auto-discovering compiler + flags (from `compile_commands.json`, a Makefile dry-run, DWARF in nearby objects, or defaults). Writes a `.o` + `.meta.json` sidecar. |
| `loci build diff`     | `--prev`, `--curr` (both required), `--verbose`                                                                                                                                                   | Compares two `.meta.json` records — informational only; a mismatch is a finding (`data.match: false`), never an error.                                                                          |
| `loci build print`    | `--meta` (required), `--verbose`                                                                                                                                                                  | Shows the build settings recorded for a compiled source.                                                                                                                                        |
| `loci build snapshot` | `--source` (required), `--project-root`                                                                                                                                                           | Freezes a source's `.o` + `.meta.json` as `.o.prev` before an edit, so `post-edit` can diff against it.                                                                                         |

### timing

| Command       | Key flags                                                                | Notes                                                                                                                                                                        |
| ------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `loci timing` | `--csv-text` or `--csv-file` (one required), `--architecture` (required) | Sends a per-block timing CSV (produced by `loci elf asm`) to the LOCI backend; returns predicted `execution_time_ns`, `std_dev_ns`, `energy_ws` per block. Requires sign-in. |

### usage

| Command      | What it does                                                          |
| ------------ | --------------------------------------------------------------------- |
| `loci usage` | Your plan, daily/weekly quota, and usage dashboard. Requires sign-in. |

### stats / trends

| Command                     | Key flags                                                                                                                                                                              | What it does                                                                                              |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `loci trends`               | `--context-file`, `--function NAME`                                                                                                                                                    | Alias for `loci stats trend`. Measurement history for one or all tracked functions on the current branch. |
| `loci stats trend-line`     | `--function f1,f2` (required), `--context-file`                                                                                                                                        | Compact recent-values line per function.                                                                  |
| `loci stats summary`        | `--context-file`                                                                                                                                                                       | One-line summary of this branch's recorded activity.                                                      |
| `loci stats global-summary` | —                                                                                                                                                                                      | Summary across all your projects since first use.                                                         |
| `loci stats record`         | `--skill` (required), `--functions N`, `--mcp-calls N`, `--co-reasoning N`, `--verdict TEXT`, `--gates JSON`, `--commit SHA`, `--context-file`                                         | Records a completed skill run (called by the skills themselves, not typically by hand).                   |
| `loci stats measure`        | `--skill` (required), `--function` or `--stdin`, `--worst-ns`, `--happy-ns`, `--energy-uws`, `--stack-bytes`, `--rom-bytes`, `--heap-sites`, `--heap-static-b`, `--commit`, `--source` | Records per-function measurements (called by the skills themselves).                                      |

### doctor

| Command       | What it does                                                                                                                                                                                     |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `loci doctor` | Read-only environment diagnostics — Python version, analysis-stack imports, `c++filt`, credential store, sign-in state, state-directory writability. Public (works signed out); mutates nothing. |

### Related pages

* [Authenticating](/loci-plugin-for-ai-coding-assistants/loci-claude-plugin/authenticating-loci-claude-plugin) — the login gate this reference assumes throughout
* [Skills Reference](/loci-plugin-for-ai-coding-assistants/loci-claude-plugin/skills-reference-for-loci-claude-plugin) — which skills call which of these commands
* [Troubleshooting](/loci-plugin-for-ai-coding-assistants/loci-claude-plugin/troubleshooting)


# Troubleshooting

### `loci` CLI not found

1. Check it's on PATH: `command -v loci` and `loci --version`.
2. If missing, the background install may still be running or may have failed. Run `/loci:setup` to reinstall and verify — it's safe to re-run.
3. Confirm `uv` is installed (`command -v uv`) — the plugin needs it to install the CLI.
4. If the install itself failed, check `~/.loci/state/loci-cli-install.log` for the cause (commonly: `uv` can't reach PyPI, or an old `uv` version).

### A skill reports `auth_required`

Every analysis skill needs a signed-in session (see Authenticating).

1. Run `! loci login`, then retry.
2. Confirm with `! loci auth status` that it shows `signed_in`.

### A skill reports `quota_exceeded`

You're signed in, but you've hit your plan's daily limit. The error message includes the reset time and an upgrade link — this is not a bug, and retrying won't help until the window resets.

### Auto-skills didn't fire

* `loci-preflight` only runs in `/plan` mode — confirm you're describing new logic, not just asking a question.
* `loci-post-edit` only runs after edits to C/C++/Rust source files (`.c`, `.cc`, `.cpp`, `.cxx`, `.h`, `.hpp`, `.hxx`, `.rs`).
* Both compile the source themselves — they need a supported LOCI target and a working cross-compiler for it on PATH, plus a valid session context from startup. If the compiler is missing, install it (or point LOCI at it) and re-run.

### On-demand skills didn't respond

* Type `/help` to confirm LOCI is loaded and see the full skill list plus your environment status.
* Restart Claude Code from inside your project directory if the build environment wasn't detected at session start.
* Check that a cross-compiler is installed and on PATH for your target — see the Installing prerequisites table.

### Environment health check

```
! loci doctor
```

Runs 10 checks (Python version, analysis-stack imports, `c++filt`, credential store, sign-in, state directory) and reports `data.healthy: true/false` plus per-check detail. Works signed out.

### Nothing seems to work

Run `/bug-report` and describe what you expected vs. what happened. It generates a full diagnostic report — environment snapshot, a 10-point checklist, and root-cause reasoning — as a timestamped `.md` file you can share with support or load into a new Claude Code session for further investigation. It works even when LOCI is completely broken (it avoids calling any of the analysis commands that might be the thing that's failing).


# AI Binary Analysis in Your CI/CD

LOCI adds AI-based binary analysis to your CI/CD workflow.

It helps teams review performance before issues reach testing or production.

### In this section

* [Ready to integrate in Your CI/CD](/ai-binary-analysis-in-your-ci-cd/ready-to-integrate-in-your-ci-cd)
* [GitHub Integration](/ai-binary-analysis-in-your-ci-cd/quick-start-loci-github-integration)
* [Azure DevOps Integration](/ai-binary-analysis-in-your-ci-cd/quick-start-loci-azure-devops-integration)

Start with the workflow. Then use the GitHub pages for setup and examples.

***

### CI/CD Workflow

LOCI fits into your existing build workflow with two steps.

{% stepper %}
{% step %}

### Upload

Run this step right after your build.

* Upload compiled binaries to the LOCI backend.
* Start analysis immediately.
* Trigger automatic PR comments when the LOCI GitHub App is installed.
  {% endstep %}

{% step %}

### Summary

Run this step when you want results in the workflow UI.

* Wait for analysis to finish.
* Pull results back into the job.
* Show the Agent Report and Function Insights in the workflow summary.
  {% endstep %}
  {% endstepper %}

Use `upload` on every run. Add `summary` when reviewers need results inside GitHub Actions.

***

### CI/CD Benefits

LOCI adds hardware-aware analysis to your pipeline before tests finish.

### What you gain

* **Pre-test analysis** catches performance and hardware interaction issues early.
* **Autonomous optimization** gives concrete suggestions for bottlenecks.
* **Performance gates** help block regressions in pull requests.

### Where results appear

* In the LOCI backend after upload.
* In the workflow summary when you run `summary`.
* In pull requests and checks when the LOCI GitHub App is installed.

This helps teams catch regressions sooner and review performance in the same flow as code changes.


# Ready to integrate in Your CI/CD?

### Getting started

A quick start guide for teams that are new to **LOCI Agentic AI**.

This guide is designed to start running with LOCI as quickly as possible. By the end of this guide, you will have:

* Integrated the LOCI GitHub App or Action into your repository
* Triggered LOCI analysis as part of your CI/CD, pull request (PR) workflow
* Generated a LOCI KPI Validator as Report for a PR
* Viewed LOCI insights directly in GitHub (PR checks, comments, or reports)

This quick start focuses on validating code changes early, providing actionable performance and correctness signals, and enabling confident merge decisions with minimal setup.

{% stepper %}
{% step %}

### Upload a Binary

Use our Upload API to submit a binary file for analysis.
{% endstep %}

{% step %}

### Check Progress

Poll for analysis completion using the `/xapi-progress` endpoint.
{% endstep %}

{% step %}

### Fetch Reports & Visualizations

Retrieve structured results including control-flow graphs, feature summaries, and version comparisons.
{% endstep %}
{% endstepper %}

***

### Docs Overview

* **API Reference**: [Loci AI API](https://pypi.org/project/loci-api/)\
  Interact with our services using simple HTTP endpoints.
* **Projects and Reports**: Learn how to manage multiple projects and browse past analyses.
* **Integration Guides**: Use Loci AI in CI/CD pipelines, reverse engineering flows, or security audits.

***

{% hint style="info" %}
Need help? Reach out at <support@auroralabs.com>

Let’s automate binary analysis — at scale, with AI.
{% endhint %}


# LOCI GitHub Integration Overview

LOCI Concept Intro - What does LOCI's GitHub integration do and how it works?

LOCI is the execution signal layer for your CI pipeline. It reads compiled binaries, diffs behavior against baseline, and posts a Pushback or Pass verdict on every PR — no instrumentation, no runtime.

The **LOCI AI Agent** GitHub integration enables developers and engineering teams to automate performance analysis directly within their existing GitHub CI/CD workflows. By connecting LOCI’s hardware-aware optimization engine with GitHub Actions and the LOCI GitHub App, teams gain immediate visibility into the performance impact of every commit, build, and pull request.

<figure><img src="/files/9kRokudcBNf1nbvUO06h" alt=""><figcaption><p>Custom illustration — system-level view of LOCI in GitHub</p></figcaption></figure>

Ready to integrate? Follow the [Quick-Start](https://app.gitbook.com/o/ZFw3dndBL81eukjWL25m/s/S2ZTr9umTUpVzGSJHbuR/~/edit/~/changes/51/ready-to-integrate/quick-start) or [Technical Reference.](https://app.gitbook.com/o/ZFw3dndBL81eukjWL25m/s/S2ZTr9umTUpVzGSJHbuR/~/edit/~/changes/51/ready-to-integrate-in-your-ci-cd/technical-reference)


# LOCI GitHub Technical Reference

The **Line of Code Insights (LOCI) Agentic AI** is a powerful tool designed to predict performance inefficiencies and power spikes in your compiled binaries *before* testing or inference. It autonomously optimizes code, configurations, and serving mechanisms. By integrating the LOCI GitHub Action into your workflow, you can shift observability left, reduce resolution time, and lower costs associated with hardware and software reliability issues.

### Key Capabilities

The LOCI GitHub Action allows you to:

* **Upload** compiled binaries for in-depth performance analysis.
* View a comprehensive **Agent Report** and insights directly in your workflow summary.
* Automatically receive **Pull Request (PR) comments** with analysis results (requires the GitHub App).

### Action Modes

The action operates in two primary modes via the `mode` input:

| Mode      | Description                                                                                                                                   | Required Inputs       |
| --------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| `upload`  | Uploads compiled binaries to the LOCI backend for analysis.                                                                                   | `project`, `binaries` |
| `summary` | Waits for the analysis to complete and attaches the **Agent Report** (in Agentic Mode) and **Function Insights** to the workflow run summary. | `project`             |

### Prerequisites and Setup

Before using the action, ensure the following are configured in your repository:

#### Required Configuration

1. **GitHub Variable**: Add `LOCI_BACKEND_URL` as a GitHub Variable.
2. **GitHub Secret**: Add `LOCI_API_KEY` as a GitHub Secret.

#### Optional Configuration

1. **LOCI GitHub App**: **Install the LOCI GitHub App** on your repository to enable automatic PR comments with results and overall Performance Reviews.
2. **Agentic Summary Token**: If you are using **Agentic Mode** and want the `summary` step to display the full report in the job UI, you must provide a Personal Access Token (PAT) as a GitHub Secret named `LOCI_GITHUB_TOKEN` and pass it to the action via an environment variable:

{% code title="Workflow snippet" %}

```yaml
env:
     LOCI_GITHUB_TOKEN: ${{ secrets.LOCI_GITHUB_TOKEN }} # required only for agentic summary
```

{% endcode %}

### Usage Examples

The action is sourced from `auroralabs-loci/loci-action@v1`.

#### Example 1: Build + Upload

This minimal example checks out code, builds a binary, and uploads it to LOCI for analysis.

{% code title=".github/workflows/loci-build-upload.yml" %}

```yaml
name: LOCI Integration
on:
  pull_request:
    types: [opened, synchronize, reopened]

env:
  LOCI_PROJECT: GHDemo

jobs:
  build-and-upload:
    runs-on: ubuntu-latest
    steps:
      - name: Prepare environment
        run: |
          sudo apt-get update
          sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu

      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Build sample
        run: |
          mkdir -p samples/build/bin
          aarch64-linux-gnu-g++ -o samples/build/bin/sample_01 samples/sample_01.cpp

      - name: Upload Artifacts
        uses: auroralabs-loci/loci-action@v1
        env:
          LOCI_API_KEY: ${{ secrets.LOCI_API_KEY }}
          LOCI_BACKEND_URL: ${{ vars.LOCI_BACKEND_URL }}
        with:
          mode: upload
          project: ${{ env.LOCI_PROJECT }}
          binaries: samples/build/bin/
```

{% endcode %}

#### Example 2: Build + Upload + Summary

This example adds the `summary` step, which waits for the analysis to complete and embeds the report and insights directly into the workflow run summary.

{% code title=".github/workflows/loci-build-upload-summary.yml" %}

```yaml
jobs:
  build-upload-and-summary:
    runs-on: ubuntu-latest
    steps:
      # ... (Your build and checkout steps here) ...

      - name: LOCI Upload
        uses: auroralabs-loci/loci-action@v1
        env:
          LOCI_API_KEY: ${{ secrets.LOCI_API_KEY }}
          LOCI_BACKEND_URL: ${{ vars.LOCI_BACKEND_URL }}
        with:
          mode: upload
          project: ${{ env.LOCI_PROJECT }}
          binaries: samples/build/bin/

      - name: LOCI Summary
        uses: auroralabs-loci/loci-action@v1
        env:
          LOCI_API_KEY: ${{ secrets.LOCI_API_KEY }}
          LOCI_BACKEND_URL: ${{ vars.LOCI_BACKEND_URL }}
          LOCI_GITHUB_TOKEN: ${{ secrets.LOCI_GITHUB_TOKEN }} # Only needed for agentic summary in job summary
        with:
          mode: summary
          project: ${{ env.LOCI_PROJECT }}
          top-n-symbols: 10 # Optional: customize the number of functions shown
```

{% endcode %}

### Inputs

| Input           | Required                | Default               | Description                                                                                                                                   |
| --------------- | ----------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `mode`          | **Yes**                 | —                     | Operation to perform: `upload` or `summary`.                                                                                                  |
| `project`       | **Yes**                 | —                     | Project name to tag the analysis results.                                                                                                     |
| `binaries`      | **Yes** (for `upload`)  | —                     | Newline-separated list of binary paths, glob patterns, or a directory. Required for `upload`, ignored for `summary`.                          |
| `target`        | No                      | `<branch>@<shortSHA>` | Project version label. Auto-resolves if not set.                                                                                              |
| `base`          | No                      | PR merge base         | Base version to compare against. Empty unless set or PR context is used.                                                                      |
| `top-n-symbols` | **Yes** (for `summary`) | `5`                   | Number of functions shown in function insights during the `summary` step.                                                                     |
| `token`         | No                      | `${{ github.token }}` | GitHub token used for merge-base detection in PRs.                                                                                            |
| `wait-base`     | No                      | `true`                | Whether to wait for the base version's processing to finish. Only relevant if `base` is provided and not yet processed.                       |
| `optimize`      | No                      | `false`               | Whether to use the LOCI Coding Agent to optimize uploaded binaries (`upload` mode only). Ignored if the PR author is the LOCI Agentic AI bot. |

### Outputs

| Output    | Description                                                          |
| --------- | -------------------------------------------------------------------- |
| `target`  | The resolved project version name for this run.                      |
| `base`    | The resolved base version name (may be empty).                       |
| `summary` | The LOCI Agent Summary Report (only available when `mode: summary`). |

### LOCI Features and Modes Overview

LOCI supports a **Standard Mode** and a more comprehensive **Agentic Mode**, which is generally enabled per company/configuration.

| Feature                            | Standard Mode              | Agentic Mode               | GitHub App Required? | Where it Appears                                                                                  |
| ---------------------------------- | -------------------------- | -------------------------- | -------------------- | ------------------------------------------------------------------------------------------------- |
| **Upload of binaries**             | ✅ Yes                      | ✅ Yes                      | ❌ No                 | LOCI Dashboard (always)                                                                           |
| **Execution Metrics**              | ✅ Yes (via `summary` step) | ✅ Yes (via `summary` step) | ❌ No                 | Workflow run summary (`summary` step)                                                             |
| **LOCI Agent Performance  Review** | ❌ Not available            | ✅ Yes                      | ✅ For PR comment     | <ol><li>Workflow run summary (<code>summary</code> step) </li><li>PR comment (LOCI App)</li></ol> |
| **Performance Per Binary**         | ❌ Not available            | ✅ Yes                      | ✅ Yes (App only)     | GitHub Checks tab (pass/fail based on `loci.yml` config)                                          |

Key Workflow Logic:

* The **`upload` step** is always required to send binaries to the LOCI backend.
* The **`summary` step** is optional and is only needed if you want the LOCI report and insights within the workflow run summary itself.
  * In **Standard Mode**, the summary step adds **Function Insights** only.
  * In **Agentic Mode**, the summary step adds the **Agent Summary Report** plus **Function Insights**.
* If the **GitHub App is installed** (and Agentic Mode is enabled), it automatically handles:
  * Posting the **LOCI Agent Summary Report as a PR comment**.
  * Enabling the **Performance Review Check Run** (pass/fail status based on configuration).
* If `optimize: true` is set on the `upload` step, the LOCI Coding Agent attempts to optimize the uploaded binaries automatically (ignored for PRs authored by the LOCI bot itself, to avoid loops).


# LOCI Azure DevOps Integration Overview

AZURE Concept Intro

LOCI guards every PR in Azure DevOps. Upload compiled binaries from your pipeline, receive a Pushback or Pass verdict on every pull request, and block merges that breach your quality contract — no instrumentation, no runtime.

The **LOCI Azure DevOps** integration enables developers and engineering teams to automate performance analysis directly within their existing Azure CI/CD workflows. By connecting LOCI's hardware-aware optimization engine with Azure Pipelines and the LOCI Azure DevOps extension, teams gain immediate visibility into the performance impact of every commit, build, and pull request

<figure><img src="/files/gDKxGNVkwKl9NRd6AgiW" alt=""><figcaption><p>Visualization of how LOCI operates within AZURE DevOps</p></figcaption></figure>

Ready to integrate? Follow the [Quick-Start](/ai-binary-analysis-in-your-ci-cd/quick-start-loci-azure-devops-integration) or [Technical Reference](https://app.gitbook.com/o/ZFw3dndBL81eukjWL25m/s/S2ZTr9umTUpVzGSJHbuR/~/edit/~/changes/52/ready-to-integrate-in-your-ci-cd/loci-azure-devops-technical-reference).


# LOCI Azure DevOps Technical Reference

This extension contributes an Azure DevOps Pipelines task (`LociTask@1`) that uploads compiled binaries to the LOCI backend for performance analysis. It is the Azure DevOps counterpart of the [`auroralabs-loci/loci-action`](https://github.com/auroralabs-loci/loci-action) GitHub Action.

***

### Prerequisites and Setup

#### Required Configuration

1. **LOCI dashboard** — Sign in as a company user, open **Company Details → Edit**, tick the **agentic** checkbox, and save. Copy your API key — you will need it for the `LOCI_API_KEY` pipeline secret.
2. **Project repository URL** — Open your LOCI project and set **repository-url** to the full Azure DevOps repo URL. Without it, the bot cannot route PR replies to the correct repository.
3. **Pipeline variables** — Add the following to your pipeline or variable group:
   * `LOCI_BACKEND_URL` — pipeline variable
   * `LOCI_API_KEY` — pipeline **secret** (copied from the dashboard)
   * `LOCI_AZURE_PAT` — pipeline **secret** (generated below)
4. **Dedicated LOCI bot user** — Create a dedicated Azure DevOps user for LOCI. Generate a long-lived PAT with the following scopes and store it as `LOCI_AZURE_PAT`:
   * **Code** (Read & Write)
   * **Identity** (Read)
   * **Pull Request Threads** (Read & Write)
   * **Tokens** (Read & Manage)

#### Optional Configuration

1. **Bot identity binding** — Set the bot user's Azure DevOps display name as the `AZURE_BOT_IDENTITY` env var on the LOCI backend so the bot recognises its own comments and `@<bot-name>` mentions:

   ```yaml
   azureDevops:
     botIdentity: "loci auroralabs"
   ```
2. **Service hook** — Required for @ chat to respond inline on PR threads. In Azure DevOps go to Project Settings → Service hooks → Create subscription, choose Web Hooks, set the trigger to Pull request commented on, and point the URL to \<dash\_url>/webhook/azure. If you add a Basic auth password on the subscription, configure the same value as SERVICE\_HOOK\_PASSWORD on the LOCI backend.

### **Dedicated LOCI bot user**

Create a dedicated Azure DevOps user — the "LOCI bot" — that owns the PAT used for SCM API calls and posts the PR comments. Whatever **display name Azure DevOps shows for that user must be set on the LOCI backend as the `AZURE_BOT_IDENTITY` env var** so the bot recognizes its own comments and mentions. The `@<bot-name>` placeholder used throughout this README refers to that same value. Example:

```yaml
azureDevops:
botIdentity: "loci auroralabs"
```

Generate a long-lived PAT for that user with the following scopes:

* **Code** (Read & Write)
* **Identity** (Read)
* **Pull Request Threads** (Read & Write)
* **Tokens** (Read & Manage)

Store the PAT as an Azure DevOps pipeline secret (e.g. `LOCI_AZURE_PAT`) and pass it to the task as `scmToken`. The first task run uploads the token to the LOCI backend, which then uses it for the async post-upload calls (PR comments, `@<bot-name>` chat) that fire after the build ends. You can verify the stored token's validity in the LOCI dashboard under your project's **Personal Access Token** field (top-right of the project view).

### **Service hook for PR chat**

Register a service hook to propagate PR comment events from Azure DevOps to the LOCI backend — without it, the backend never sees the comments and `@<bot-name>` chat can't respond. In Azure DevOps go to **Project Settings → Service hooks → Create subscription**, choose **Web Hooks**, and set **Trigger on this type of event** to **Pull request commented on**. Set the URL to `<dash_url>/webhook/azure`. If you set a Basic authentication password on the subscription, that same value must be configured on the backend as the `SERVICE_HOOK_PASSWORD` env var (username is ignored).

### Azure DevOps pipeline setup

Set these on the pipeline (or as variable group entries):

* `LOCI_BACKEND_URL` — pipeline variable.
* `LOCI_API_KEY` — pipeline **secret** variable (copied from the LOCI dashboard above).
* `LOCI_AZURE_PAT` — pipeline **secret** variable holding the bot PAT generated above; passed to the task as `scmToken`.

### **Usage Examples**

#### **Example 1: Build + Upload**

```yaml
trigger:
  branches:
    include: [main]
pr:
  branches:
    include: [main]

pool:
  vmImage: 'ubuntu-latest'

variables:
  LOCI_PROJECT: AzureDevOpsDemo

steps:
  - checkout: self
    fetchDepth: 0
    persistCredentials: true

  - script: echo "Build project here"
    displayName: 'Build project'

  - task: LociTask@1
    name: LOCI_Upload
    displayName: 'LOCI Upload'
    inputs:
      mode: upload
      project: $(LOCI_PROJECT)
      binaries: path/to/your/binaries/
      scmToken: $(LOCI_AZURE_PAT)
    env:
      LOCI_API_KEY: $(LOCI_API_KEY)
      LOCI_BACKEND_URL: $(LOCI_BACKEND_URL)
```

### **Inputs**

<table><thead><tr><th width="129">Input</th><th width="115" align="center">Required</th><th width="240" align="center">Default</th><th>Description</th></tr></thead><tbody><tr><td><code>mode</code></td><td align="center">✅</td><td align="center"><code>upload</code></td><td>Operation to perform. v1 supports <code>upload</code> only.</td></tr><tr><td><code>project</code></td><td align="center">No</td><td align="center"><code>$(Build.Repository.Name)</code></td><td>LOCI project name to tag analysis results under. Defaults to the Azure DevOps repository name when omitted; set explicitly to override.</td></tr><tr><td><code>binaries</code></td><td align="center">✅</td><td align="center">—</td><td>Newline-separated list of binary paths, glob patterns, or a directory. Non-ELF entries are filtered out.</td></tr><tr><td><code>target</code></td><td align="center">No</td><td align="center"><code>&#x3C;branch>@&#x3C;shortSHA></code></td><td>Project version label for this run. Auto-resolved from build context; set explicitly to override.</td></tr><tr><td><code>base</code></td><td align="center">No</td><td align="center">PR merge base on PR builds</td><td>Base version to compare <code>target</code> against. Auto-resolved on PRs; set explicitly to override (or to force a comparison on non-PR builds).</td></tr><tr><td><code>waitBase</code></td><td align="center">No</td><td align="center"><code>true</code></td><td>Wait for the base version's processing to finish before uploading the target. Comparison analysis cannot run otherwise — leave on unless you specifically want to fail fast.</td></tr><tr><td><code>scmToken</code></td><td align="center">✅</td><td align="center">—</td><td>Long-lived Azure DevOps PAT used by LOCI for SCM API calls. Pass via a pipeline secret, e.g. <code>scmToken: $(LOCI_AZURE_PAT)</code>.</td></tr></tbody></table>

### Token Rotation

To rotate the LOCI bot's Personal Access Token: navigate to User Settings → Personal access tokens in Azure DevOps and revoke the existing token. Generate a new PAT for the same bot user with identical scopes - Code (Read & Write), Identity (Read), Pull Request Threads (Read & Write), Tokens (Read & Manage) - and copy the new token value. In your Azure DevOps pipeline, open Pipelines → Library (or the pipeline's Variables panel), locate the LOCI\_AZURE\_PAT secret variable, and replace it with the new token. No pipeline code changes are required; the updated secret takes effect on the next pipeline run.

### **Outputs**

| Variable      | Kind                                 | Description                                                |
| ------------- | ------------------------------------ | ---------------------------------------------------------- |
| `target`      | Step output (`$(<stepName>.target)`) | Resolved project version name for this run.                |
| `base`        | Step output (`$(<stepName>.base)`)   | Resolved base version name (may be empty).                 |
| `LOCI_TARGET` | Pipeline variable (`$(LOCI_TARGET)`) | Same value as `target`, available to all downstream tasks. |
| `LOCI_BASE`   | Pipeline variable (`$(LOCI_BASE)`)   | Same value as `base`, available to all downstream tasks.   |

***

### Viewing results

Open the **LOCI Upload** step's log and look at the last line — the task prints the LOCI dashboard URL there. On PR builds, the same analysis is also one click away from **Checks → Performance overview**, whose target URL deep-links straight to the latest comparison view.

***

### Rotating the SCM PAT

Azure DevOps PATs expire.&#x20;

To rotate, update the pipeline secret/variable (e.g. `LOCI_AZURE_PAT`) with the new token — the next task run uploads it to the LOCI backend and replaces the stored copy used for async post-upload calls (PR comments, `@<bot-name>` chat).&#x20;

If the old token expires before the next build runs, paste the new token directly into the project's **Personal Access Token** field in the LOCI dashboard to unblock those calls immediately. The project view shows an error indicator when the stored token is no longer valid.

***

### Troubleshooting

**Base version is missing.** The comparison can't run because the resolved base isn't available. The usual causes are: the base branch was never uploaded to LOCI, the base upload is still processing and `waitBase: false` was set, or the base's own analysis failed. Make sure the base branch has a successful LOCI run to compare against; for in-flight processing, keep `waitBase: true` (the default) so the task polls until the base is ready.

**Account is not configured for agentic mode.** Some features require the company to be agentic. In the LOCI dashboard, sign in as a company user, open **Company Details → Edit**, tick the **agentic** checkbox, and save (or ask a LOCI admin to do it).

**`@<bot-name>` chat isn't responding.** Check that **repository-url** is set on your LOCI project (see above) and that the service hook for **Pull request commented on** is registered and pointing at `<dash_url>/webhook/azure` with the matching `SERVICE_HOOK_PASSWORD` on the backend.


# Quick-Start LOCI Azure DevOps Integration

The **LOCI Azure DevOps** integration enables developers and engineering teams to automate performance analysis directly within their existing Azure Pipelines CI/CD workflo +ws. By connecting LOCI's hardware-aware optimization engine with Azure Pipelines and the `LociTask@1` extension task, teams gain immediate visibility into the performance i +mpact of every commit, build, and pull request — with findings delivered as PR thread comments before merge.

#### User Flow Overview

<figure><img src="/files/AbzkNcIQReXThigxOfHa" alt=""><figcaption></figcaption></figure>

**Setup steps (1–3)** are performed once per repository.&#x20;

**Usage steps (4–5)** repeat automatically on every pull request.

***

### Step-by-Step Guide

#### **Step 1 — Install the LOCI Azure DevOps Extension**

Install the **LOCI Azure DevOps Extension** from the [Azure DevOps Marketplace](https://marketplace.visualstudio.com/azuredevops). This extension provides the `LociTask@1` pipeline task that uploads your compiled binaries to the LOCI backend for hardware-aware performance analysis.

An active LOCI license is required. Contact <support@auroralabs.com> to obtain one.

#### **Step 2 — Add Your Credentials and Configure the Bot**

**LOCI dashboard** — Sign in as a company user, open **Company Details → Edit**, tick the **agentic** checkbox, and save. Copy your API key for the next step.

Add the following to your Azure DevOps pipeline:

* `LOCI_API_KEY` — pipeline **secret** variable (your LOCI API key)
* `LOCI_AZURE_PAT` — pipeline **secret** variable (the bot user PAT generated below)
* `LOCI_BACKEND_URL` — pipeline variable (not secret)

**Bot user** — Create a dedicated Azure DevOps user for LOCI. Generate a long-lived PAT for that user with the following scopes: **Code** (Read & Write), **Identity** (Read), **Pull Request Threads** (Read & Write), **Tokens** (Read & Manage). Store it as `LOCI_AZURE_PAT`. Also set **repository-url** on your LOCI project to the full Azure DevOps repo URL — without it the bot cannot route PR replies to the correct repository.

**Service hook** — In Azure DevOps go to **Project Settings → Service hooks → Create subscription**, choose **Web Hooks**, set the trigger to **Pull request commented on**, and point the URL to `<your_loci_dashboard_url>/webhook/azure`. This enables `@<bot-name>` chat to respond inline on PR threads.

#### **Step 3 — Add LociTask\@1 to Your Pipeline**

Add `LociTask@1` to your `azure-pipelines.yml` after your build step:

```yaml
trigger:
  branches:
    include: [main]
pr:
  branches:
    include: [main]

pool:
  vmImage: 'ubuntu-latest'

variables:
  LOCI_PROJECT: my-project

steps:
  - checkout: self
    fetchDepth: 0
    persistCredentials: true

  - script: echo "Build project here"
    displayName: 'Build project'

  - task: LociTask@1
    name: LOCI_Upload
    displayName: 'LOCI Upload'
    inputs:
      mode: upload
      project: $(LOCI_PROJECT)
      binaries: path/to/your/binaries/
      scmToken: $(LOCI_AZURE_PAT)
    env:
      LOCI_API_KEY: $(LOCI_API_KEY)
      LOCI_BACKEND_URL: $(LOCI_BACKEND_URL)
```

#### **Step 4 — Open a Pull Request**

Opening a PR against your target branch triggers the pipeline automatically. LOCI detects which functions changed between the PR branch and the base, runs hardware-aware execution analysis, and compares results against the baseline — no manual intervention required.

#### **Step 5 — Review the LOCI Report**

LOCI posts its findings as PR thread comments from the **loci-review** bot. Each comment includes execution timing deltas, control-flow analysis, and optimization recommendations grounded in real hardware traces. Mention `@<bot-name>` in any PR thread to query the analysis inline.

Results are also accessible via the dashboard URL printed in the `LociTask@1` task logs. On the **Checks** tab of your PR, select **Performance overview** for a full side-by-side comparison.

***

#### Next Steps

* [Explore the LOCI Azure DevOps Integration Overview](https://docs.loci-dev.net/ready-to-integrate-in-your-ci-cd/loci-azure-devops-integration-overview)
* [Explore the full Azure DevOps Technical Reference](https://docs.loci-dev.net/ready-to-integrate-in-your-ci-cd/loci-azure-devops-technical-reference)
* [LOCI for Azure DevOps README file](https://github.com/auroralabs-loci/loci-action/blob/azure_devops_support/azure/README.md)


# Quick-Start LOCI GitHub Integration

LOCI Quick-Start User Flow

The **LOCI AI Agent** GitHub integration enables developers and engineering teams to automate performance analysis directly within their existing GitHub CI/CD workflows. By connecting LOCI's hardware-aware optimization engine with GitHub Actions and the LOCI GitHub App, teams gain immediate visibility into the performance impact of every commit, build, and pull request.

***

### User Flow Overview

<figure><img src="/files/TdXcJaK7i9p1dyGxRGiq" alt=""><figcaption></figcaption></figure>

**Setup steps (1–3)** are performed once per repository.&#x20;

**Usage steps (4–5)** repeat automatically on every pull request.

***

### Step-by-Step Guide

#### Step 1 — Install the LOCI GitHub App

Go to <https://github.com/marketplace/loci-agentic-ai> and install the app on your repository. This enables LOCI to post automated performance analysis comments directly on your pull requests. An active LOCI license is required (free plans available).

***

#### Step 2 — Add Your Credentials to GitHub

In your repository settings, add two values:

* `LOCI_API_KEY` — as a GitHub Secret
* `LOCI_BACKEND_URL` — as a GitHub Variable

Optionally add `LOCI_GITHUB_TOKEN` to enable workflow summary integration. These credentials connect the LOCI Action to your licensed backend.

***

#### Step 3 — Add the LOCI Action to Your CI Workflow

Add the [LOCI Action](https://github.com/marketplace/actions/loci-action) to your existing `.github/workflows` file. The action runs in two steps: **upload** (build and ship your binary after compilation) and **summary** (wait for analysis and attach the Agent Report to the workflow run).

This snippet is a single step — add it to the `steps:` list of a job in your existing `.github/workflows` file, after your build step.

<pre class="language-yaml"><code class="lang-yaml"><strong>- name: Upload to LOCI
</strong>  uses: auroralabs-loci/loci-action@v1
  env:
    LOCI_BACKEND_URL: '${{ vars.LOCI_BACKEND_URL }}'
    LOCI_API_KEY: '${{ secrets.LOCI_API_KEY }}'
  with:
    mode: upload
    project: my-project
</code></pre>

***

#### Step 4 — Open a Pull Request

Push a branch and open a PR as normal. LOCI automatically detects the changed functions, compiles the before/after binaries, and runs hardware-aware analysis — no manual trigger needed.

***

#### Step 5 — Review the LOCI Report

LOCI posts its findings directly in the PR as a comment from the `loci-review` \[Bot]. The report includes:

* Execution timing and energy deltas per changed function
* Flame graph comparison between base and target versions (when relevant)
* Control-flow analysis highlighting call-depth changes
* Agent Summary with optimization recommendations and a pass/fail performance check

***

### Next Steps

* [Explore the full PR Insights Report in LOCI Inspector](/loci-inspector)
* [Explore the full GitHub Actions reference](https://github.com/marketplace/actions/loci-action)
* [View a live example PR](https://github.com/auroralabs-loci/llama.cpp/pull/1361)


# LOCI Inspector

Your Execution-Aware Code Dashboard

LOCI Inspector is a centralized hub for exploring execution-aware insights across your projects. It allows you to understand the impact of code changes on performance, correctness, and resource usage without running the software in production.

With LOCI Inspector, you can:

* **Visualize** function-level performance and resource usage across versions
* **Explore** call graphs and execution paths to quickly identify hotspots
* **Drill down** into pull request changes with actionable insights
* **Compare** versions and track regressions over time

The visualizations in LOCI Inspector make it easy to identify issues, optimize performance, and make confident decisions throughout the development lifecycle.


# Sign-in to LOCI

To access LOCI, you need to sign in. Signing in gives you secure access to your company workspace, lets you manage your data, and allows you to continue your work seamlessly - whether you’re analyzing results, collaborating with your team, or tracking progress.

LOCI supports two ways to sign in:

## **Sign in with a LOCI account**

If your account was created directly in LOCI, go to the LOCI sign-in page and enter your email address and password.\
If you’re logging in for the first time, make sure you’ve confirmed your account via the invitation or confirmation email before attempting to sign in.

## **Sign in with GitHub**

You can also sign in using your GitHub account. This option allows you to authenticate directly through GitHub and automatically links your GitHub identity with your LOCI workspace, enabling seamless access to repositories and related features.

<figure><img src="/files/EQhacQV9NhEfyyEPrtSq" alt=""><figcaption><p>Sign In to LOCI</p></figcaption></figure>

Once signed in, you’ll have full access to LOCI features relevant to your company, with your information kept secure at all times.


# Create Project

## Create New Project

In order to start using LOCI you must create a project (or work on an existing project in the LOCI Dashboard).

{% stepper %}
{% step %}

### Enter the project manually

* Enter Project Name: Enter your Project Name manually.
* Select Architecture manually
* Enter Project Description: Any details relevant and important for the project.

<figure><img src="/files/EsC0UKn1Gl47jDE6vbCi" alt=""><figcaption><p><em>Create a project</em></p></figcaption></figure>

<figure><img src="/files/SZ1GZlk1W413mHy5MGVv" alt=""><figcaption><p><em>Create a new project</em></p></figcaption></figure>
{% endstep %}

{% step %}

### Link the project automatically for a GitHub Repository

By providing the GitHub repository link, the project is directly linked to the corresponding GitHub repository, enabling seamless integration with pull requests and commits. Once connected, LOCI automatically analyzes changes as they are introduced, ensuring continuous, execution-aware feedback without additional manual setup.

<figure><img src="/files/Toip2cG8AGkI0jAoF2Hx" alt=""><figcaption><p><em>Link the project from a GitHub Repo</em></p></figcaption></figure>

<figure><img src="/files/SZ1GZlk1W413mHy5MGVv" alt=""><figcaption><p><em>Link a new project</em></p></figcaption></figure>
{% endstep %}

{% step %}

### Create the project

Create the new project by clicking the “Submit” button.

<figure><img src="/files/eIbSeThJhhXTWPjfqRw9" alt=""><figcaption><p><em>Create the project in LOCI</em></p></figcaption></figure>
{% endstep %}

{% step %}

### The project appears in the list

After the project is created it appears under the Projects list on the sidebar where all projects are listed. When the project is linked to its GitHub repository, the GitHub icon is displayed as enabled in the top-right corner, indicating an active connection.

<figure><img src="/files/23z5t3CW1573EMesGcG8" alt=""><figcaption><p><em>Verify the project is created</em></p></figcaption></figure>
{% endstep %}
{% endstepper %}

***

## Upload New Version in the Project

To upload a new software version for a project, provide the following information and start the upload.

{% stepper %}
{% step %}

### Provide version details

#### Manually created prjects

* Enter Version Name
* Upload Binary
* Select version to compare (if there is any)
* Select the architecture

![Enter Project Version details](/files/e35cecfe6c4bf2014915188f848bf5d6dea00050)
{% endstep %}

{% step %}

#### Automatically linked projects from a GitHub Repository

Since these projects are automatically connected to LOCI, pull requests from the linked GitHub repository are processed automatically. This means LOCI immediately analyzes new changes and generates execution-aware insights for each PR without any manual intervention, streamlining review and feedback.
{% endstep %}

{% step %}

### Start upload

Begin the upload. The new project version starts uploading and progress will be shown.

!\[Project Version starts to upload

]\(/files/dec8ebbdfc57253dfa26fed9db5a23b08a0314c5)
{% endstep %}
{% endstepper %}


# LOCI Progress Details

After the version starts with upoload, the Progress Details Page opens for a transparent and detailed view over the details related to this process.

{% stepper %}
{% step %}

### Analysis Phase

File uploading and validation - File uploading and validation is the process of submitting files to the system and verifying their format, integrity, and compliance with defined requirements.

<figure><img src="/files/KRQs7qp2RRl1OSjyk8ki" alt=""><figcaption><p><em>Analysis Phase</em></p></figcaption></figure>
{% endstep %}

{% step %}

### Pre-processing Phase

Identifying functions and detection of function changes - Pre-processing is the phase where functions are identified and any changes to their structure or behavior are detected.

<figure><img src="/files/mpokvxqXnLD1UPkl2ZGY" alt=""><figcaption><p><em>Pre-processing step</em></p></figcaption></figure>
{% endstep %}

{% step %}

### LCLM Inference Phase

LCLM Inference (Creating timing analysis, performance degradation, function dependency detection and comparison reports) - LCLM Inference is the phase where timing analysis is performed, performance degradation is assessed, function dependencies are detected, and detailed comparison reports are generated.

<figure><img src="/files/9mziQOO7eiI4YWCkyLaA" alt=""><figcaption><p><em>Inference step</em></p></figcaption></figure>
{% endstep %}

{% step %}

### Results

Results - Generation of reports and process finishing, a phase where final reports are generated and the overall process is completed

<figure><img src="/files/NxnS02wNo8LN58ZQPX9A" alt=""><figcaption><p><em>Results</em></p></figcaption></figure>
{% endstep %}
{% endstepper %}

While the process of uploading runs the version on the Project Overview Page shows with status “In progress”. Depending on the status in which the version is the following statuses can be seen:

* **In Progress:** Your binary file is currently being uploaded to LOCI. Please wait while the system processes the file. Larger files may take a little longer depending on your connection speed.
* **Failed:** The upload was not successful. This could be due to an unsupported file format, a network issue, or a server-side error. Double-check the file and try again. If the problem continues, please contact support.
* **Completed:** Your binary file has been uploaded successfully. You can now proceed with the next steps, such as analyzing the file or starting your workflow in LOCI.

<figure><img src="/files/Sa89mhEgBYSFQrPKRja2" alt=""><figcaption><p align="center"><sup><em><mark style="color:$info;">Project Version ‘status’</mark></em></sup></p></figcaption></figure>

When the upload is successfully finalized the User can navigate to:

* Go to the **"Processing Details" Page**

<figure><img src="/files/10edee2cfd03e1dde4eb5d7b88b5cce0f3135ea1" alt=""><figcaption><p align="center"><sup><em><mark style="color:$info;">View Version Insights</mark></em></sup></p></figcaption></figure>

* Go to the "**Project Overview" Page** for next steps (upload new binary or review the list of versions related to the specific Project)

<figure><img src="/files/bJ7pG7eJYNnCK4FIpwkK" alt=""><figcaption><p align="center"><sup><em><mark style="color:$info;">Project Overview Page</mark></em></sup></p></figcaption></figure>

<p align="center"></p>


# Insights

Deep Dive into Code Performance and Changes

LOCI Insights provides a detailed view of your project’s execution-aware data, helping teams understand how code changes affect performance, correctness, and resource usage. It transforms raw analysis into actionable information, making it easier to prioritize fixes, spot regressions, and optimize critical functions.

With LOCI Insights, you can:

* **Break down metrics** by function and module per pull request
* **Sort and filter** data to focus on the changes that matter most
* **Visualize trends** over time to track performance improvements or regressions

LOCI Insights turns complex code analysis into clear, actionable intelligence, enabling faster, data-driven decisions throughout the development lifecycle.


# Visualization

In the **Charts**, performance degradation is presented for a single version or as a comparison between two versions. It is visually represented as:

#### Single version

* **Blue Bars:** Performance of Target Version

<figure><img src="/files/beb9affcd497a2ac8718a31eadd07d288a19aa1f" alt=""><figcaption><p align="center"><sup><em><mark style="color:$info;">Performance of Target Version</mark></em></sup></p></figcaption></figure>

#### Comparison

* **Green Bars:** Performance of Base Version (Version with which the Target Version is compared to)
* **Blue Bars:** Performance of Target Version

<figure><img src="/files/ONBoWco7IediPXQeJZ3Q" alt=""><figcaption><p align="center"><sup><em><mark style="color:$info;">Performance of Base Version compared to Target Version</mark></em></sup></p></figcaption></figure>

<p align="center"></p>


# Report Metrics Breakdown

In the **Report Metrics Breakdown**, the following metrics are used to assess performance degradation:

<table><thead><tr><th width="152">Metric</th><th>Description</th></tr></thead><tbody><tr><td><strong>Binary</strong></td><td>Specify the binary name containing the function.</td></tr><tr><td><strong>Function</strong></td><td>The name of the function.</td></tr><tr><td><strong>Response</strong></td><td>Response Time [ns]: The average (mean) execution time of a function.</td></tr><tr><td><strong>Throughput</strong></td><td>Top deviated metric shows the functions that have the biggest change in absolute time of execution or in other words the functions with biggest delta in the execution time (throughput).</td></tr><tr><td><strong>Bottleneck</strong></td><td>This metric highlights the functions with the most significant performance bottlenecks, focusing on the most time consuming segment of code within one function, that doesn't include the execution time of the callee function (i.e., caller > callee).</td></tr><tr><td><strong>Diff [%]</strong></td><td>The percentage difference in execution time between the Base and Target versions. A positive value indicates a speed up, while a negative value indicates slowing down.</td></tr></tbody></table>


# Sorting in the Reports

In the Report, the list is sorted by any column.

![The list is sorted by any column
](/files/c60844e78024f6d59d3e55513a1c21d705ba14bf)


# Execution Metrics Worst-Case Response, Throughput & Bottleneck \[Chart]

The chart identifies functions with the greatest absolute change in execution/response time between two points of comparison (Target and Base) — for example different builds, configurations, or code versions. The change is measured in delta units of time (not percentages) to emphasize functions that have the most impact on overall performance shifts, regardless of their relative size. This helps you quickly spot which parts of the codebase have regressed or improved the most in terms of raw throughput (for example, total execution time).

To keep the report focused on significant performance changes, only functions with a time deviation greater than 100 nanoseconds are visualized. This threshold filters out minor fluctuations that are unlikely to meaningfully affect overall performance, helping you concentrate on the most critical regressions or optimizations.

## Filters implemented on the Report

* Binaries: Select All or a specific binary
* Status: All, Modified, New, Removed, Unchanged
* Filter Functions: Search a function and filter it in the report
* Timing displayed: Responce, Throughput, or Bottleneck

Notes on conditional display:

* If there is only one version uploaded (Target), the “Functions” filter is not shown.
* If there is only one binary in the version, the “Binaries” filter is not shown.

<figure><img src="/files/3oJsXt5dx8uiZdNVCXfg" alt=""><figcaption><p><sup><em>Single version - greatest absolute change in execution time</em></sup></p></figcaption></figure>

<figure><img src="/files/wGk4PNoZCzDsf7erK2XN" alt=""><figcaption><p><sup><em>Comparing two versions (Base and Target) - greatest absolute change in execution time</em></sup></p></figcaption></figure>


# Response Time (with collees)

This metric surfaces the functions contributing the most to total runtime by including both their self-time and the time spent in callees. This view provides insight into which functions represent major performance bottlenecks in the system, even if the time is distributed across a large call tree. It leverages segment-level timing predictions and call graph traversal to compute the full execution cost of each function.

<figure><img src="/files/Ds4seJXB7MPV8OLQNF80" alt=""><figcaption><p>Execution Metrics: Worst-Case Response Time</p></figcaption></figure>


# Throughput Time (w/o collees)

Top deviated metric shows the functions that have the biggest change in absolute execution time (throughput) — i.e., the functions with the largest delta in execution time.

This metric identifies functions with the most significant self-time degradation — execution time spent exclusively in the function itself, excluding callees. By leveraging segment-based time prediction and respecting call-site boundaries, the report isolates function-level performance regressions with higher accuracy.

The report focuses on functions that take the most execution time on their own and ignores time spent in child functions (callees). The time spent in callees is dropped by how assembly segments are sliced in our processing and how the LCLM model is trained: we predict time on segments and then calculate the time without callees. Assembly segments in our processing never cross function call-site boundaries, which enables this isolation.

<figure><img src="/files/JYXgDP56iWgnhnQGignZ" alt=""><figcaption><p>Execution Metrics: Throughput Time</p></figcaption></figure>


# Top Bottleneck In Functions

This metric highlights the functions with the most significant performance bottlenecks, focusing on the most time-consuming segment of code within one function that doesn't include the execution time of the callee function (i.e., caller > callee).

<figure><img src="/files/SSdXszFkoC9D1SZJ7VDg" alt=""><figcaption><p>Execution Metrics: Bottleneck Time</p></figcaption></figure>


# Call Graph Analysis

The "Call Graph" option provides a configuration interface that allows you to filter and select various parameters to achieve your preferred CFI view. The ability to configure the CFI filters is important for tailoring the analysis to your specific needs.

The user can apply the following CFI filters to adjust the CFI graph visualization:

* **Select Specific Binary**
* **Filter Function** — quickly find and focus on a function within the CFI graph

Implemented filters on the CFI Graph

<figure><img src="/files/rquQiGEm0roBxpLW66DP" alt=""><figcaption><p>LOCI Call Graph</p></figcaption></figure>

Utilize the CFI graph to ensure accurate filtration and representation per binary.

Filter by Binary/s

<figure><img src="/files/i6ooXdPMef5RxeMcMJ2c" alt=""><figcaption><p>LOCI Call Graph - 'Binaries', Filter per binary</p></figcaption></figure>

The user can locate a specific function within the CFI Graph using the "Filter Functions..." option, which filters only the selected function within the graph.

<figure><img src="/files/bVPIOHJNF51dmJKb6RzP" alt=""><figcaption><p>LOCI Call Graph - 'Filter Functions...' option</p></figcaption></figure>

The user can focus on a specific function within the CFI Graph using the "Focus on function..." option, which highlights and focuses on the selected function within the graph.

<figure><img src="/files/yEUz1zMHzR1ABIqB7vtN" alt=""><figcaption><p>LOCI Call Graph - 'Focus on function...' option</p></figcaption></figure>

<figure><img src="/files/dLVOqdsxvv4nQPyUehPh" alt=""><figcaption><p>LOCI Call Graph - 'Focus on a specific function</p></figcaption></figure>


# Call Graph Inspector

The Call Graph Inspector renders the function call graph for a selected project version as an interactive, progressively expandable graph. The initial view surfaces the highest-impact functions ranked by Response Time. From there, the full graph is explored node by node through on-demand expansion. The canvas supports scroll-to-zoom and click-and-drag panning; any node can be repositioned by dragging.

<figure><img src="/files/OzRs3DOHVGFx6K5oC7bG" alt=""><figcaption><p>Call Graph Inspector</p></figcaption></figure>

***

### Graph Layout and Containers

Functions appear as nodes grouped in color-coded cluster subgraphs — one cluster per binary. Each cluster carries a draggable label identifying the binary. Nodes move freely anywhere on the canvas.

When multiple binaries are selected, all are loaded simultaneously and cross-binary call edges are drawn wherever they exist.

***

### Nodes

Each node represents a single function from the analyzed binary. The node label shows the short function name. Clicking a node opens its **Expansion Panel**, which displays the fully-qualified name alongside the three timing metrics below.

#### Timing Metrics

| Metric              | Definition                                                                        |
| ------------------- | --------------------------------------------------------------------------------- |
| **Response Time**   | Worst-case time from function entry to exit, including all time spent in callees. |
| **Throughput Time** | Worst-case time from function entry to exit, excluding time spent in callees.     |
| **Bottleneck Time** | Worst-case time spent consecutively inside the function body.                     |

All three values display in the most readable unit (ns / µs / ms / s). A dash (`--`) indicates no data was recorded for that function.

#### Node Colors

| Color  | Meaning                                         |
| ------ | ----------------------------------------------- |
| Blue   | Default — function is rendered but not selected |
| Orange | Selected — the most recently clicked function   |

***

### Relations

Each directed edge represents an observed call from one function to another, derived directly from collected execution traces.

#### Edge Labels

Every edge shows a call count — the number of times that specific call was recorded across all collected execution traces.

#### Edge Colors

Colors are relative to the currently selected node and reset each time the selection changes.

| Color  | Meaning                                                           |
| ------ | ----------------------------------------------------------------- |
| Gray   | Default — not connected to the selected node, or no node selected |
| Orange | Outgoing — the call originates from the selected function         |
| Purple | Incoming — the call terminates at the selected function           |

#### Edge Style

All edges are Bézier curves with a triangle arrowhead pointing toward the callee. Self-referencing calls (recursive functions) render as looped arcs.

***

### Expansion Panel

Clicking any function opens the Expansion Panel, which shows:

* **Function name** — short and fully-qualified
* **Response Time**, **Throughput Time**, and **Bottleneck Time** for that function
* **Incoming edges** — count of edges currently visible versus total available
* **Outgoing edges** — same counter

Edges are added directly from the panel in two ways:

| Button         | Action                                              |
| -------------- | --------------------------------------------------- |
| **+10**        | Loads the next 10 edges in that direction           |
| **Expand All** | Loads all remaining edges in that direction at once |

***

### Initial Graph Load

On load, the graph surfaces a ranked subset of functions and a bounded number of edges per function. Functions with the highest Response Time load first — the most impactful call chains are always visible by default.

Load limits are adjustable in the **Advanced Options** panel:

| Setting                        | Default | Description                                                                              |
| ------------------------------ | ------- | ---------------------------------------------------------------------------------------- |
| Total Functions (Maximum)      | 50      | Upper bound on functions loaded across all selected binaries                             |
| Functions per Binary (Minimum) | 10      | Each binary contributes at least this many functions, even when the total cap is reached |
| Edges per Function (Maximum)   | 3       | Number of outgoing edges loaded per function in the initial view                         |

***

### Filtering and Search

The filter bar accepts a text query matched against function names. Three match modes are available:

| Mode                | Behavior                                      |
| ------------------- | --------------------------------------------- |
| Substring (default) | Functions whose name contains the query       |
| Whole Word          | Functions whose name exactly equals the query |
| Regex               | Treats the query as a regular expression      |

Case sensitivity toggles independently of the match mode.

The filter panel also provides:

* **Binary selection** — show or hide individual binaries
* **Advanced Options** (tune icon) — adjust the load limits described above

Applying new filter settings clears the current graph and reloads it from scratch.

<figure><img src="/files/mFT60rXDhurbqQJ5zwdb" alt=""><figcaption><p>Filter Functions</p></figcaption></figure>

<figure><img src="/files/ps8PvN7v88vJVvt8o62F" alt=""><figcaption><p>Focus on Function</p></figcaption></figure>

***

### Toolbar Controls

| Control                         | Action                                                                                 |
| ------------------------------- | -------------------------------------------------------------------------------------- |
| **Focus on function…** dropdown | Centers and zooms the viewport onto any visible function and opens its Expansion Panel |
| **Reset**                       | Clears the graph and reloads with the current filter settings                          |
| **Zoom Out**                    | Fits the entire graph into the viewport                                                |

***

### Tooltips

Hovering over an edge shows a tooltip identifying the source and target functions:

```
<source function> → <target function>
```

The tooltip follows the cursor and disappears when the cursor leaves the edge.

<figure><img src="/files/qNaVSXJWSeryQRdYm4e1" alt=""><figcaption><p>Visualized relations on the Call Graph</p></figcaption></figure>


# CLI

The **Loci CLI** provides a fast and secure way to interact with the LOCI Platform directly from your terminal.

Use it to manually upload binaries and track analysis progress.

{% hint style="info" %}
This section covers `loci_api`, the CI/CD & self-hosted API client. This id not the Claude Code plugin's `loci` CLI, which installs itself automatically ([Install LOCI plugin](https://app.auroralabs.com/)).&#x20;
{% endhint %}


# Installation

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* Python 3.9+
* `pip` installed
* (Optional) A virtual environment

***

### Installation <a href="#installation" id="installation"></a>

Install the CLI via `pip`:

```
pip install loci-api
```


# Configuration

{% hint style="info" %}
These variables are required for proper working of the Loci API.
{% endhint %}

### Environment Variables

After installing the package you will need to configure the API key and Loci Binary Analysis backend URL for further usage of the API module.

```bash
export LOCI_API_KEY='YOUR-KEY'
export LOCI_BACKEND_URL='https://prod.api.loci-dev.net/ (edited)'
```

For the original documentation, see: <https://docs.loci-dev.net/CLI/cli-config/#environment-variables>


# Usage

### CLI utility

This guide covers common workflows using the **Loci CLI**, which enables seamless interaction with the Loci AI Binary Analysis platform directly from your terminal.

#### Available commands

list-projects, list-versions, last-version, upload, upload-last, status, func-insights, flame-graph, whoami

List existing projects:

{% code title="Command" %}

```bash
loci_api list-projects
```

{% endcode %}

Example:

{% code title="Example" %}

```bash
$ python -m loci_api list-projects
[
    "OpenSSL"
]
```

{% endcode %}

List all versions for a project:

{% code title="Command" %}

```bash
loci_api list-versions <project-name>
```

{% endcode %}

Example:

{% code title="Example" %}

```bash
$ python -m loci_api list-versions OpenSSL
[
    "1.1.1",
    "3.1.4"
]
```

{% endcode %}

Get latest valid version for a project:

{% code title="Command" %}

```bash
loci_api last-version <project-name>
```

{% endcode %}

Example:

{% code title="Example" %}

```bash
$ python -m loci_api last-version OpenSSL
[
    "3.1.4"
]
```

{% endcode %}

Upload new version:

{% code title="Commands" %}

```bash
loci_api upload <path-to-binary> <project-name> <new-version-name> [--compare-version-name version-name]
loci_api upload-last <path-to-binary> <project-name> <new-version-name>
```

{% endcode %}

Get function insights:

{% code title="Command" %}

```bash
loci_api func-insights <project-name> <version-name> [--version-name-base <base-version-name>] [--perc-resp-limit <percentage>] [--perc-thro-limit <percentage>] [--perc-bott-limit <percentage>] [--pairs <func1> <bin1> ...]
```

{% endcode %}

Example:

{% code title="Example" %}

```bash
$ python -m loci_api func-insights "OpenSSL" "3.1.4" --version-name-base="1.1.1" --perc-resp-limit=20 --pairs asn1_str2type libcrypto.so asn1_str2tag libcrypto.so
[
    {
        "total_count": "17294",
        "binary_name": "libcrypto.so",
        "function_long_name": "asn1_gen.c_asn1_str2tag",
        "function_name": "asn1_str2tag",
        "source_location": "/tmp/tmpqubfnl76/crypto/asn1/asn1_gen.c:503:566;",
        "mean_bottleneck": null,
        "std_bottleneck": null,
        "mean_throughput": 269.44492,
        "std_throughput": 18.811226,
        "mean_response": 506.63327,
        "std_response": 18.811226,
        "mean_bottleneck_base": null,
        "std_bottleneck_base": null,
        "mean_throughput_base": 264.7869,
        "std_throughput_base": 18.811226,
        "mean_response_base": 282.73398,
        "std_response_base": 18.811226,
        "perc_throughput": "1.8",
        "perc_response": "79.2",
        "perc_bottleneck": null
    },
    {
        "total_count": "17294",
        "binary_name": "libcrypto.so",
        "function_long_name": "asn1_gen.c_asn1_str2type",
        "function_name": "asn1_str2type",
        "source_location": "/tmp/tmpqubfnl76/crypto/asn1/asn1_gen.c:579:586;",
        "mean_bottleneck": null,
        "std_bottleneck": null,
        "mean_throughput": 2087.0325,
        "std_throughput": 77.55288,
        "mean_response": 2771728,
        "std_response": 77.55288,
        "mean_bottleneck_base": null,
        "std_bottleneck_base": null,
        "mean_throughput_base": 1799.3105,
        "std_throughput_base": 77.55288,
        "mean_response_base": 16767339,
        "std_response_base": 77.55288,
        "perc_throughput": "16.0",
        "perc_response": "-83.5",
        "perc_bottleneck": null
    }
]
```

{% endcode %}

Get flame graph:

{% code title="Command" %}

```bash
loci_api flame-graph <project-name> <version-name> [---function-name <function_name>] [--binary-name <binary-name>]
```

{% endcode %}

Example:

{% code title="Example" %}

```bash
$loci_api flame-graph seoul_test main@46943b6 --function-name main --binary-name build.bin.demo_arm64
[{"low":130,"high":137,"x":-3,"name":"feature_load_from_nvm","id":22,"value":7},{"low":525,"high":532,"x":-3,"name":"feature_load_from_nvm","id":22,"value":7},{"low":539,"high":544,"x":-3,"name":"feature_save_to_nvm","id":23,"value":5},{"low":598,"high":605,"x":-3,"name":"__stack_chk_fail@GLIBC_2.17@plt","id":3,"value":7},{"low":68,"high":75,"x":-2,"name":"feature_load_from_nvm","id":22,"value":7},{"low":79,"high":88,"x":-2,"name":"drive_mode_init","id":20,"value":9},{"low":91,"high":100,"x":-2,"name":"blink_init","id":11,"value":9},{"low":104,"high":110,"x":-2,"name":"ambient_init","id":8,"value":6},{"low":127,"high":137,"x":-2,"name":"uds_init","id":27,"value":10},{"low":145,"high":150,"x":-2,"name":"feature_save_to_nvm","id":23,"value":5},{"low":154,"high":161,"x":-2,"name":"ambient_set_target","id":9,"value":7},{"low":179,"high":269,"x":-2,"name":"blink_update","id":12,"value":90},{"low":272,"high":310,"x":-2,"name":"ambient_tick","id":10,"value":38},{"low":324,"high":331,"x":-2,"name":"__printf_chk@GLIBC_2.17@plt","id":2,"value":7},{"low":351,"high":394,"x":-2,"name":"can_pack_VehDynA","id":13,"value":43},{"low":412,"high":419,"x":-2,"name":"__printf_chk@GLIBC_2.17@plt","id":2,"value":7},{"low":441,"high":606,"x":-2,"name":"uds_handle","id":26,"value":165},{"low":615,"high":622,"x":-2,"name":"__printf_chk@GLIBC_2.17@plt","id":2,"value":7},{"low":651,"high":658,"x":-2,"name":"__printf_chk@GLIBC_2.17@plt","id":2,"value":7},{"low":695,"high":702,"x":-2,"name":"puts@GLIBC_2.17@plt","id":25,"value":7},{"low":706,"high":735,"x":-2,"name":"drive_mode_set","id":21,"value":29},{"low":742,"high":749,"x":-2,"name":"__printf_chk@GLIBC_2.17@plt","id":2,"value":7},{"low":0,"high":787,"x":-1,"name":"main","id":24,"value":787}]
```

{% endcode %}

Check authentication status:

{% code title="Command" %}

```bash
loci_api whoami
```

{% endcode %}

Example:

{% code title="Example" %}

```bash
$loci_api whoami
Company: AL Agentic Company
Agentic: Yes
Max users: 100
Created at: 2025-10-30T11:40:13.074Z
Active until: undefined
```

{% endcode %}

***

### Python Module

Example Python script for a common workflow using the **loci\_api** python module.

#### Binary Upload example python script

{% code title="upload\_binary.py" %}

```python
import sys
import time
from loci_api import api_helper

if __name__ == "__main__":

    # input params
    file_path = sys.argv[1]
    version_name = sys.argv[2]
    platform = sys.argv[3]
    project_name = sys.argv[4]

    project_id = api_helper.get_project_id(project_name)
    if project_id is None:
        print("Uploading failed, Project does not exist.")
        sys.exit(-1)

    compare_version_id = api_helper.get_last_version_id(project_id)
    reportId = api_helper.upload_binary(file_path, version_name, compare_version_id, project_id, platform)

    if reportId != '':
        print(f"Uploaded binary Report ID: {reportId}, Compare Version ID: {compare_version_id}, Project ID: {project_id}")
    else:
        print("Uploading failed, See previous message for more details.")
        sys.exit(-1)

    finished = False
    status = 0

    print("Waiting for processing to finish")
    while not finished:
        finished, status = api_helper.upload_finished(project_id, reportId)
        time.sleep(10)

    sys.exit(status)
```

{% endcode %}


# Module Reference

## upload\_binary

```python
def upload_binary(file_path, version_name, compare_version_id, project_id,
                  platform)
```

Uploads a file via POST request

Arguments:

* `file_path` *str* - Path to the file to upload
* `version_name` *str* - the version name of the new version to be created
* `compare_version_id` *str* - the version id against which we compare the new binary, if empty no comparison will be made
* `project_id` *str* - the project id of the project for which we are creating the version
* `platform` *str* - the platform of the new version (ARM|TRICORE)
* `scm_metadata` *SCMMetadata* - An object containing source control metadata used to provide context about the project and versions being compared.

Returns:

* `report_id` - report id of the new report comparing the new version vs the compare\_version

***

## get\_last\_version\_id

```python
def get_last_version_id(project_id)
```

Gets the version id of the latest valid version uploaded for the project

Arguments:

* `project_id` *str* - the project id for which we are getting the latest version

Returns:

* `version_id` *str* - the version id of the latest valid version uploaded for the project or '' if not found
* `version_name` *str* - the version name of the latest valid version uploaded for the project

***

## get\_versions

```python
def get_versions(project_id)
```

Returns list of all version objects for the project

Arguments:

* `project_id` *str* - the project's id for which we are getting the version objects

Returns:

* `versions` *\[Object]* - list of version objects for the project or \[] if none found

***

## get\_project\_id

```python
def get_project_id(project_name)
```

Returns the project id for the project with the given project name

Arguments:

* `project_name` *str* - the name of the project we are searching

Returns:

* `project_id` *str* - project id for the matched project or '' if not found
* `platform` *str* - the defined platform for the matched project or '' if not found

***

## get\_projects

```python
def get_projects()
```

Returns list of all project objects for the company

Arguments: None

Returns:

* `projects` *\[Object]* - list of project objects for the company

***

## upload\_finished

```python
def upload_finished(project_id, report_id)
```

Checks the status of the report with given report id

Arguments:

* `project_id` *str* - the project's id for which the report was created
* `report_id` *str* - the report id of the report we are uploading

Returns:

* `(finished, status)` *(boolean, int)* - returns the status of the upload

***

## get\_function\_insights

```python
def get_function_insights(version_id, version_id_base=None, perc_resp_limit=None,
                          perc_thro_limit=None, perc_bott_limit=None, pairs=None)
```

Returns a list of function insight objects containing performance metrics for the specified version.

Arguments:

* `version_id` *str* - id of the project version to retrieve function insights for
* `version_id_base` *str* (optional) - id of the base version to compare against
* `perc_resp_limit` *int* (optional) - minimum percentage change in response time required for a function to be included in the results
* `perc_thro_limit` *int* (optional) - minimum percentage change in throughput required for a function to be included in the results
* `perc_bott_limit` *int* (optional) - minimum percentage change in bottleneck required for a function to be included in the results
* `pairs` *\[Object]* (optional) - list of objects, each with `function_name`: *str* and `binary_name`: *str* fields, specifying which functions to return insights for

Returns:

* `function_insights` *\[Object]* - list of function insight objects for the specified version or an empty list if none are found

***

## get\_flame\_graph

```python
def get_flame_graph(project_id, version_id, source_container,
                          source_long_name)
```

Returns the flame graph for a specified function.

Arguments:

* `project_id` *str* - id of project
* `version_id` *str* - id of the project version
* `source_container` *str* - binary/container of the function
* `source_long_name` *str* - function long name

Returns:

* `flame_graph` *str* - string of the json representation of the flame graph for the specified function

***

## get\_version\_status

```python
def get_version_status(project_id, version_id)
```

Returns the status of a provided project version.

Arguments:

* `project_id` *str* - id of project
* `version_id` *str* - id of the project version to retrieve function insights for

Returns:

* `status_details` *dict|None* - A mapping with the structure below, or None if not found:

```json
{
  "status": int,
  "total": int,
  "counts": {
    "passed": int,
    "failed": int,
    "pending": int
  },
  "updated_at": str,
  "analysis": [
    {
      "binary": str,
      "step": str,
      "status": int,
      "updated_at": str
    },
    ...
  ]
}
```

***

## get\_report\_data

```python
def get_report_data(report_id)
```

Returns report symbols data.

Arguments:

* `report_id` *str* - id of report

Returns:

* `report_data` *dict|None* - A mapping with the structure below, or None if not found:

```json
{
  "target_total": int,
  "base_total": int,
  "modified": int,
  "new": int,
  "deleted": int
}
```

***

## get\_function\_insights\_summary

```python
def get_function_insights_summary(project_id, version_id, version_id_base, repository, pr_number)
```

Returns agent summary. In order for this to work, an environment variable `LOCI_GITHUB_TOKEN` that holds a GitHub PAT (Personal Access Token) is required.

Arguments:

* `project_id` *str* - id of project
* `version_id` *str* - id of target version
* `version_id_base` *str* - id of base version
* `scm_metadata` *SCMMetadata* - An object containing source control metadata used to provide context about the project and versions being compared.

Returns:

* `summary` *str|None* - An AI agent summary for the specified comparison or None if it is not generated.


# LOCI Support

Reach out at <support@auroralabs.com>

Let’s automate binary analysis at scale, with AI.


# LOCI Release Notes

LOCI predicts what AI-generated code will do — time, power, memory, and system behavior — during planning, code writing, and every pull request, before any of it runs. This section tracks every release across both surfaces: the Claude Code plugin and binary analysis in your CI/CD pipeline — what shipped, what's fixed, and what's next.


# LOCI Binary Analysis in Your CI/CD Release Notes

AI has solved software generation. LOCI solves software understanding — for every pull request. Wherever your coding agents ship code, LOCI reads the compiled binary and catches what a source-level review can't see, before it merges. Here's what's changed, release by release.


# LOCI v0.9.3.480 · May 23, 2025

## This release broadens what LOCI can ingest and makes call graphs and flame graphs easier to read.

## New

* **Broader archive support** — Upload version archives in `.tar.gz`, `.tar.bz2`, and `.tar.xz`, in addition to existing formats.
* **Directory structures and symlinks** — Uploaded archives can now include full directory structures and symlinks; LOCI processes them correctly.
* **Automatic filtering of irrelevant files** — Unsupported or irrelevant files inside an uploaded archive are now ignored automatically instead of blocking processing.

## Improved

* **Clearer call graphs** — Cross-library calls are now visualized with each library in its own color, making interconnections between libraries easier to follow.
* **Clearer flame graphs** — Child functions beneath a selected parent are now visually distinguished, so hierarchy is obvious at a glance.

## Fixed

* **Podman binary processing** — Fixed an issue where Podman binaries could get stuck at the finalize-report stage.

Questions or feedback? <loci@auroralabs.com>


# LOCI v0.9.4.90 · June 9, 2025

## Reports get a redesign, and search now reaches your whole codebase, not just what's on screen.

## New

* **Global symbol search** — Search returns results from your entire symbol set, not just what's visible in the current view — including on the control-flow graph, where a searched symbol now appears even if it wasn't part of the default view.

## Improved

* **Bottleneck-aware flame graphs** — Flame graphs now visually highlight the functions actually driving total response time, along with their callees, styled distinctly from non-critical functions.
* **Consolidated performance report** — Response Time and Throughput Time reports are merged into one report, with clearer columns, per-function drill-down detail, an integrated flame graph, and consolidated sort, search, and filter controls.
* **Full-data report downloads** — Downloaded reports now include the entire dataset, not just what's visible by default.
* **Cleaner report view** — Removed trend arrows from reports for a simpler, less cluttered view.

Questions or feedback? <loci@auroralabs.com>


# LOCI v0.9.4.173 · June 26, 2025

## A cleanup pass on the dashboard and reports, focused on showing less noise and more signal.

## Improved

* **Function-level change tracking** — The Execution Metrics report now shows exactly which functions were modified, added, or removed between versions.
* **Simplified Version Insights header** — Project name and target version now lead the page; the comparison version and processing timestamp move to a second row, shown only when relevant.
* **Streamlined dashboard** — Retired the Function Type report and Behavior Impact section; source-location detail moved into the function-level drill-down instead of cluttering the top-level report.

Questions or feedback? <loci@auroralabs.com>


# LOCI v0.9.4.210 · July 14, 2025

## A stability- and accuracy-focused release — no new features, several correctness fixes.

## Fixed

* **More accurate modified-function detection** — Fixed undercounting of modified functions in external libraries when comparing base and target versions.
* **Correct sorting with a single version** — Fixed incorrect metric sort order when only a base version exists.
* **Scoped impact reporting** — Fixed a bug where a change to one class was incorrectly reported as impacting unrelated libraries.

Questions or feedback? <loci@auroralabs.com>


# LOCI v0.9.5.11 · August 1, 2025

## Another stability release, focused on the mobile experience and results integrity.

## Fixed

* **Mobile project selector** — Fixed a loading issue in "Select Project" on mobile; the project list now appears immediately, and the sidebar closes automatically after selection.
* **Blocked early access to incomplete results** — View Insights is no longer accessible for a version until processing is fully complete.

Questions or feedback? <loci@auroralabs.com>


# LOCI v0.9.5.128 · September 17, 2025

## LOCI's prediction engine gets more consistent, and you can now see exactly why, down to the assembly block.

## New

* **Assembly-level control-flow viewer** — View disassembled assembly for both the base and comparison version directly in the dashboard, with function- and instruction-level navigation, execution metrics correlated to specific assembly blocks, and an integrated control-flow graph showing branches, loops, and call paths.

## Improved

* **More consistent predictions** — Recalibrated the prediction model to reduce variation caused by block address position and worst-case-path selection in the control-flow graph, for more stable results across builds.

Questions or feedback? <loci@auroralabs.com>


# LOCI 0.9-dev-gf07c77f (build 61) · December 12, 2025

## LOCI GitHub Action & App — Build 61 · April 12, 2025

LOCI now has public, runnable proof on real-world codebases.

### New

* **Real-world reference integrations** — LOCI's GitHub Action and App now run against FreeRTOS, LLaMA, and OpenSSL, giving teams concrete, inspectable examples of execution-aware analysis on production-scale software, not toy benchmarks.

Questions or feedback? <loci@auroralabs.com>


# LOCI v0.9-dev-ga7bddba (build 118) · January 30, 2026

## New

* **GitHub comment integration** — Bring comments from GitHub directly into the chat agent, so PR discussion context carries straight into your LOCI conversation.

## Improved

* **Quick re-processing of versions** — Re-process a previously uploaded version directly from the LOCI Dashboard, without a fresh upload.
* **GitHub integration for project creation** — Create and see new projects through GitHub integration, directly from the Dashboard.
* **Agentic AI on real Rust projects** — LOCI's GitHub integration now runs its Agentic AI analysis against nextest, nushell, and gitoxide — three real, Rust-based open-source projects.

Questions or feedback? <loci@auroralabs.com>


# LOCI v0.9-dev-g3ae761c (build 171) · February 16, 2026

## Broader silicon coverage, a clearer per-PR review experience, and deeper integration with coding agents like Claude Code.

## New

* **Broader hardware and architecture support** — LOCI now supports ARMv9 alongside ARMv8, with benchmarking validated across S32G2, Cortex-M4, and Infineon TriCore silicon.
* **LOCI Review & LOCI Inspector** — Every pull request now gets a clear, KPI-driven performance and safety assessment through LOCI Review. LOCI Inspector lets you debug and explore results interactively, and every report tells you exactly how to ask a follow-up question or request a deeper look, right from the PR.
* **Deeper coding-agent integration** — LOCI's API now supports richer integrations: coding agents like Claude Code can generate and analyze assembly-level execution data directly inside your existing workflow, no manual handoff required.
* **Enterprise on-premises deployment** — LOCI is now packaged for on-premises deployment, for teams with strict data-residency or security requirements.

## Improved

* **More accurate predictions** — LOCI's prediction engine now reasons more deeply before returning a verdict, for more accurate and more reliable results.
* **Faster, more consistent at scale** — Infrastructure improvements mean predictions return faster and hold up consistently, even under heavy load.

Questions or feedback? <loci@auroralabs.com>


# LOCI Plugin for AI Coding Assistants Release Notes

Coding agents write code. LOCI thinks ahead — right inside Claude Code. Plan Guard checks the plan before Claude writes a line; Save Guard checks the binary the moment it does. Here's what's changed, release by release.


# LOCI v0.1 · July 2, 2026

Coding agents write code. LOCI thinks ahead: it predicts what AI-generated code will do — time, power, memory, and system behavior — during planning and code writing, before any of it runs. Now directly inside Claude Code, at exactly those two moments: Plan Guard while Claude drafts a plan, Save Guard the instant it writes.

## New

Two stations run automatically, the moment Claude plans or writes:

* **Plan Guard (`loci-preflight`)** — Before Claude writes a line of code, LOCI audits the plan at the binary level — timing, power, and control-flow impact of the functions involved — and returns a verdict: `GOOD`, `ADJUST PLAN`, or `STOP`.
* **Save Guard (`loci-post-edit`)** — Every source edit is compiled and diffed against the pre-edit binary automatically. LOCI returns a per-function regression verdict — `OK`, `CAUTION`, or `FLAG` — and proposes a fix when it flags one.

Five more are yours to call on directly, in plain language:

* **`exec-trace`** — Ask *"What's the execution cost of `main()`?"* and get function-level timing and power, grounded in real workloads and platform traces, with a confidence band on every number.
* **`stack-depth`** — Ask *"Is my stack safe for `TaskMain`?"* and get worst-case stack depth along the deepest call path, checked against your budget, with RTOS task entry points detected automatically (`xTaskCreate`, `Task_construct`, `osThreadNew`, `FreeRTOSConfig.h`).
* **`memory-report`** — Ask *"How much ROM/RAM does my build use?"* and get a section-by-section breakdown of the compiled binary and its top consumers.
* **`control-flow`** — Ask *"Show me the call graph for `process_data()`."* and get an annotated control-flow graph — every branch, every call edge — with indirect-call hazards flagged by name.
* **`trends`** — Ask *"How are my functions doing?"* and get per-function timing, power, stack, and memory history on the current branch, broken down by improved, regressed, and baseline.

Plus three that keep the other five running smoothly:

* **`/help`** — Shows your environment status, sign-in state, and the full skill list, with a contextual next step.
* **`/loci:setup`** — Reinstalls and repairs the `loci` CLI. Idempotent — safe to run any time something looks off.
* **`/bug-report`** — Generates a full diagnostic report when a skill doesn't fire the way you expect.

And the record of all of it:

* **LOCI Portal** — Every run from Claude Code is logged automatically, with a Sessions log, configurable gate thresholds, and PR-level review against your open pull requests.
* **Session hooks** — `SessionStart` detects your project and build environment automatically; `PreToolUse` snapshots the binary ahead of every edit so Save Guard has a baseline to diff against.

## Good to know

* Every result comes from the compiled binary directly — no profilers, no runtime instrumentation, no connected board, and no source code changes.
* The gate is advisory, not automatic: LOCI proposes a verdict, a human makes the final call.
* `stack-depth`, `memory-report`, and `control-flow` run entirely from the local binary — no MCP connection or network dependency required.

## Prerequisites

| Requirement                                | Version | Needed for                                              |
| ------------------------------------------ | ------- | ------------------------------------------------------- |
| Claude Code                                | Latest  | Everything                                              |
| Python                                     | 3.12+   | The `loci` CLI (local ELF/build analysis)               |
| uv                                         | Any     | Installing the `loci` CLI                               |
| jq                                         | Any     | Session hooks                                           |
| Compiled binaries (`.elf` / `.o` / `.axf`) | —       | All skills                                              |
| Network access to the LOCI backend         | —       | Plan Guard, Save Guard, on-demand timing/power analysis |

One cross-compiler, matched to the target: `arm-none-eabi-gcc` (ARM Cortex-M), `aarch64-linux-gnu-gcc` (ARM Cortex-A), `tricore-elf-gcc` (TriCore), `tiarmclang` or `armcl` (TI ARM), `g++` or `clang++` (x86/x64). `stack-depth`, `memory-report`, and `control-flow` run without a cross-compiler or MCP connection at all.

***

LOCI works alongside Claude Cod. This is our first release for Claude Code specifically — more AI Agents Cursor, Copilot, and your own agents; deeper CI/CD integration; and broader toolchain coverage are next.

Questions or feedback? <loci@auroralabs.com>


# LOCI v0.1.111 · July 30, 2026

## A stability and accuracy release — twelve fixes across Plan Guard, Save Guard, the on-demand skills, and the Portal. No new capabilities this time.

## Fixed

* **`loci login` no longer crashes on Windows in Git Bash** — A conflicting OpenSSL library pulled in from Git's own toolchain was aborting the CLI the moment it opened its first secure connection. Login now works normally from any shell.
* **Accurate worst-case stack results** — Fixed `stack-depth`'s assembly parser reading hexadecimal stack-pointer offsets as zero, which could understate worst-case stack usage.
* **`exec-trace` now analyzes the latest build** — Fixed `exec-trace` running against a stale compiled binary instead of the newest one after a source change.
* **ARMv6 timing restored** — Fixed timing analysis returning no results for ARMv6 targets because the prediction model was unavailable.
* **Correct instruction-to-prediction mapping** — Fixed the timing prediction service returning results out of order, which could mismatch assembly instructions with their predicted timing.
* **Accurate Save Guard performance diffs** — Fixed the Performance row comparing two different calculations as if they were the same metric, which could produce a misleading delta.
* **Reliable Save Guard diffing on Rust crates** — Fixed before/after comparisons falling back to absolute numbers only, for the rest of a session, after the first edit inside a multi-file Rust crate.
* **No more redundant recompiles in Save Guard** — Fixed Save Guard recompiling a file from scratch even when Plan Guard had already compiled it earlier in the same session.
* **Correct target detection on `/loci:setup`** — Fixed `/loci:setup` picking up a stale target architecture left over from a previous project when no project was actually open.
* **No more silent failures on missing output folders** — Fixed LOCI failing silently when a required output directory didn't exist, instead of creating it or surfacing the error.
* **Code Health insights load correctly** — Fixed the Code Health page in the Portal showing empty when telemetry had stopped updating.
* **Correct session count in the Usage tab** — Fixed the Portal's Usage tab undercounting the number of sessions.

***

Questions or feedback? <loci@auroralabs.com>


# API References

The LOCI REST API handles binary upload, analysis progress, and project/version data. It's the same API used internally by the `loci_api` CLI, the GitHub Action, and the Azure DevOps extension — you can also call it directly to build your own integration.

Every endpoint requires an API key, sent via the `x-api-key` header. The base URL is the LOCI backend configured for your account (the same `LOCI_BACKEND_URL` used by the CI integrations) — self-hosted deployments point at their own host, SaaS accounts use the LOCI-provided one.

This section covers uploading a binary for analysis, checking analysis progress, listing projects, and retrieving project versions. For CLI-based access instead of calling the API directly, see the CLI Reference.


# Upload binary file using API key

### Request Body — REQUIRED

| Field        | Type   |
| ------------ | ------ |
| `binaryFile` | binary |

### Responses

| Status | Description                |
| ------ | -------------------------- |
| `200`  | File uploaded successfully |
| `400`  | Bad request                |
| `401`  | Unauthorized               |


# List all projects using API key authentication

GET /api/v1/projects/xapi-list-all

Base URL: <https://prod.api.loci-dev.net>

{% hint style="info" %}
Authorize: Provide a valid API key. Requests without a valid API key will return 401 Unauthorized.
{% endhint %}

## Responses

* 200 — Projects retrieved successfully
* 401 — Unauthorized - Invalid or missing API key
* 500 — Server error

## Schema (OPTIONAL)

* success — boolean (OPTIONAL)
* data — object\[] (OPTIONAL)

Each object in `data` may contain:

* \_id — string (OPTIONAL)
* name — string (OPTIONAL)
* description — string (OPTIONAL)
* organizationId — string (OPTIONAL)
* createdAt — date-time (OPTIONAL)
* updatedAt — date-time (OPTIONAL)

{% tabs %}
{% tab title="cURL" %}
{% code title="curl" %}

```bash
curl -L 'https://prod.api.loci-dev.net/api/v1/projects/xapi-list-all' \
  -H 'Accept: application/json'
```

{% endcode %}
{% endtab %}
{% endtabs %}


# Version

## Upload binary file using API key

> Upload a binary file using API key authentication

```json
{"openapi":"3.0.0","info":{"title":"Loci AI Binary Analisis API","version":"1.0.0"},"servers":[{"url":"https://api.loci-dev.net","description":"Local Development server"}],"security":[{"apiKey":[]}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/api/v1/reports/xapi-upload":{"post":{"summary":"Upload binary file using API key","description":"Upload a binary file using API key authentication","tags":["Version"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"binaryFile":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"File uploaded successfully"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"}}}}}}
```

## Get report progress

> Get the progress of a report

```json
{"openapi":"3.0.0","info":{"title":"Loci AI Binary Analisis API","version":"1.0.0"},"servers":[{"url":"https://api.loci-dev.net","description":"Local Development server"}],"paths":{"/api/v1/reports/xapi-progress":{"post":{"summary":"Get report progress","description":"Get the progress of a report","tags":["Version"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reportId":{"type":"string"}}}}}},"responses":{"200":{"description":"Returns the report progress","content":{"application/json":{"schema":{"type":"object","properties":{"progress":{"type":"number"}}}}}},"400":{"description":"Bad request"}}}}}}
```


# Projects

## List all projects using API key authentication

> Retrieves all projects using API key authentication instead of JWT

```json
{"openapi":"3.0.0","info":{"title":"Loci AI Binary Analisis API","version":"1.0.0"},"servers":[{"url":"https://api.loci-dev.net","description":"Local Development server"}],"security":[{"apiKey":[]}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/api/v1/projects/xapi-list-all":{"get":{"summary":"List all projects using API key authentication","description":"Retrieves all projects using API key authentication instead of JWT","tags":["Projects"],"responses":{"200":{"description":"Projects retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"organizationId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Unauthorized - Invalid or missing API key"},"500":{"description":"Server error"}}}}}}
```

## Get project versions using API key authentication

> Retrieves all versions for a project using API key authentication instead of JWT

```json
{"openapi":"3.0.0","info":{"title":"Loci AI Binary Analisis API","version":"1.0.0"},"servers":[{"url":"https://api.loci-dev.net","description":"Local Development server"}],"security":[{"apiKey":[]}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/api/v1/graph/xapi-project-versions":{"post":{"summary":"Get project versions using API key authentication","description":"Retrieves all versions for a project using API key authentication instead of JWT","tags":["Projects"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string","description":"ID of the project to fetch versions for"},"organizationId":{"type":"string","description":"ID of the organization"}}}}}},"responses":{"200":{"description":"Project versions retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"version":{"type":"string"},"reportId":{"type":"string"}}}}}}}}},"401":{"description":"Unauthorized - Invalid or missing API key"},"500":{"description":"Server error"}}}}}}
```


# Intro


# Deployment Guide

### 1. Purpose <a href="#id-1.-purpose" id="id-1.-purpose"></a>

This page describes how to deploy the **LOCI** platform as a self-hosted (on-prem in your AWS account) installation using the provided **loci-box** package and **LOCI bootstrapper Docker image**.

The guide is intended for DevOps / Cloud engineers who have admin access to the target AWS account.

***

### 2. Prerequisites <a href="#id-2.-prerequisites" id="id-2.-prerequisites"></a>

Before you begin, make sure you have all of the following.

#### 2.1 AWS & Permissions <a href="#id-2.1-aws-and-permissions" id="id-2.1-aws-and-permissions"></a>

* An **AWS account** dedicated to the LOCI deployment (recommended).
* An **IAM user** or role with **AdministratorAccess** or equivalent permissions, including:
  * Full access to **ECR**, **EC2**, **VPC**, **IAM**, **CloudWatch**, **S3**, and any other LOCI-related services.
* Valid **AWS credentials** configured on the machine that will run the bootstrap container (e.g. via `aws configure` or assumed role).

#### 2.2 DNS (optional) <a href="#id-2.2-aws-dns-hosted-zone" id="id-2.2-aws-dns-hosted-zone"></a>

* A public Route 53 Hosted Zone is not required. By default, frontend/backend/Grafana are reached via ALB DNS names with a self-signed HTTPS certificate.\
  If you want a custom domain, you may use any DNS provider (AWS Route 53 or external) and optionally provide ACM certificate ARNs in `config.ini`.

#### 2.3 LOCI Assets <a href="#id-2.3-loci-assets" id="id-2.3-loci-assets"></a>

You should receive the following from the LOCI team:

* **LOCI installation key**\
  Used to authenticate and authorize your deployment.
* `loci-box.zip` **or** `loci-box.tar`\
  This archive contains:
  * `config.ini.sample` (or similar sample configuration file)
  * **This installation document** (or a link to it)
  * **Installation key file** (if provided as a file)
  * Any additional helper scripts or notes (if applicable)

> **Note:** Keep the installation key and archive in a secure location. They are unique to your organization.

#### 2.4 Local Environment <a href="#id-2.4-local-environment" id="id-2.4-local-environment"></a>

* A Linux / macOS / Windows host with:
  * **Docker** installed and running
  * Network access to:
    * `258916827218.dkr.ecr.us-east-1.amazonaws.com` (LOCI ECR)
    * Standard AWS service endpoints (EC2, VPC, IAM, etc.)
* Ability to download and unpack `zip` or `tar` archives.

***

### 3. High-Level Deployment Flow <a href="#id-3.-high-level-deployment-flow" id="id-3.-high-level-deployment-flow"></a>

1. Prepare an AWS admin user/role and configure credentials locally.
2. Unpack `loci-box.zip` / `loci-box.tar`.
3. Edit `config.ini` based on your environment and the sample file.
4. Pull and run the **LOCI bootstrapper** Docker image:
   * `258916827218.dkr.ecr.us-east-1.amazonaws.com/loci-infra:latest`
5. Wait for the deployment to complete (about **30 minutes**).
6. Perform validation checks:
   * Access to LOCI main web UI
   * Access to LOCI monitoring URL
   * Billing/Cost tags applied to infrastructure
7. If anything fails or seems unclear, contact LOCI Support.

***

### 4. Unpack LOCI Box & Prepare `config.ini` <a href="#id-4.-unpack-loci-box-and-prepare-config.ini" id="id-4.-unpack-loci-box-and-prepare-config.ini"></a>

1. Copy `loci-box.zip` / `loci-box.tar` to your deployment machine.
2. Extract the archive, for example:

   `# For tar tar -xvf loci-box.tar # For zip unzip loci-box.zip`
3. Inside the extracted directory you should see a **sample** `config.ini` file.
4. Create your working config file:

   `cp config.ini.sample config.ini`
5. Open `config.ini` in your preferred editor and update values as needed (AWS region, account details, networking preferences, installation key, etc.).

> **Important:**
>
> * Every field in `config.ini` is documented inline in the file.
> * Make sure all required values are filled in before starting the bootstrapper.
> * Keep your installation key and any secrets **out of version control**.

***

### 5. Pull and Run the LOCI Bootstrapper <a href="#id-5.-pull-and-run-the-loci-bootstrapper" id="id-5.-pull-and-run-the-loci-bootstrapper"></a>

#### 5.1 Set Helpful Environment Variables <a href="#id-5.1-set-helpful-environment-variables" id="id-5.1-set-helpful-environment-variables"></a>

From the folder where `config.ini` is located:

`export IMAGE_NAME="258916827218.dkr.ecr.us-east-1.amazonaws.com/loci-infra:latest" export CONTAINER_NAME="loci-bootstrapper"`

If your environment requires explicit ECR login, ensure you are authenticated to the ECR registry (example using AWS CLI v2):

`aws ecr get-login-password --region us-east-1 \ | docker login \ --username AWS \ --password-stdin 258916827218.dkr.ecr.us-east-1.amazonaws.com`

#### 5.2 Run the Bootstrapper and Deploy <a href="#id-5.2-run-the-bootstrapper-and-deploy" id="id-5.2-run-the-bootstrapper-and-deploy"></a>

Run the LOCI bootstrapper container in detached mode:

`docker run -d \ --name "${CONTAINER_NAME}" \ -v "$(pwd)/config.ini:/workspace/scripts/config.ini:ro" \ "${IMAGE_NAME}" --deploy`

* `-d` – runs the container in the background.
* `--name` – gives a friendly name to the container to reference later.
* `-v "$(pwd)/config.ini:/workspace/scripts/config.ini:ro"` – mounts your local `config.ini` into the container in **read-only** mode.
* `"${IMAGE_NAME}"` – the LOCI bootstrapper image.
* `--deploy` Begin deployment

#### 5.3 Monitor Deployment Progress <a href="#id-5.3-monitor-deployment-progress" id="id-5.3-monitor-deployment-progress"></a>

The deployment typically takes **around 30 minutes**.

To monitor progress:

`docker logs -f "${CONTAINER_NAME}"`

* Look for messages indicating successful creation/configuration of infrastructure resources.
* If you see obvious errors (e.g., missing config fields or AWS permission issues), stop and fix the cause, then re-run the container if needed.

***

### 6. Post-Deployment Validation <a href="#id-6.-post-deployment-validation" id="id-6.-post-deployment-validation"></a>

After the bootstrapper finishes successfully, perform the following checks.

> The exact URLs and identifiers will be provided to you as part of the LOCI onboarding or visible in the bootstrapper logs.

#### 6.1 Application UI <a href="#id-6.1-application-ui" id="id-6.1-application-ui"></a>

* Open a browser and navigate to the **main LOCI platform URL**(as populated on config.ini)
* Verify:
  * Login page or landing page loads correctly.
  * No obvious errors appear in the UI.
  * You can log in (if initial admin credentials were provided).
  * Upload sample binary provided with the loci-box and wait for successful analysis

#### 6.2 Monitoring & Observability <a href="#id-6.2-monitoring-and-observability" id="id-6.2-monitoring-and-observability"></a>

* Navigate to the main **monitoring URL** (e.g., Grafana/monitoring endpoint provided during setup).
* Verify:
  * The dashboards are accessible.
  * Basic system health panels show data (CPU, memory, key LOCI services).

#### 6.3 Billing & Tags <a href="#id-6.3-billing-and-tags" id="id-6.3-billing-and-tags"></a>

Verify that **billing tags** are applied to all LOCI infrastructure resources, according to your organization’s cost allocation standards. For example:

* In the AWS console, open the Cost Explorer and look for LOCI under tags menu,

***

### 7. Support & Contact <a href="#id-7.-support-and-contact" id="id-7.-support-and-contact"></a>

If any step fails, or if the platform does not behave as expected after deployment:

* Collect:
  * The **docker logs** of the bootstrapper container.
  * Any relevant error messages from the AWS console.
  * A brief description of what you tried and where it failed.

Then contact the **LOCI Support team**:

* 📧 Support email: *(<support@auroralabs.com>)*

> We’re here to help – if something goes wrong, don’t hesitate to reach out. The LOCI team will assist you in troubleshooting and completing your deployment successfully.


# Resources List

## Resources Created in LOCI Self-Hosted Deployment

This document lists all resources created by the standalone deployment infrastructure.

### Table of Contents

1. Infrastructure & Networking
2. EKS Cluster & Node Groups
3. Kubernetes Resources
4. AWS Services
5. Route53 & DNS
6. Monitoring & Logging
7. Security & IAM
8. Storage

***

### Notes

* All resources are tagged with cost allocation tags for tracking
* Resources follow AWS Well-Architected Framework principles
* High availability is configured for critical components (databases, node groups)
* Backup and disaster recovery configured for databases
* Monitoring and logging are comprehensive across all services
* Security follows least-privilege IAM principles
* All data is encrypted at rest and in transit

### Infrastructure & Networking

#### VPC Resources

* **VPC** (`example-cluster`)
  * CIDR: `10.3.0.0/16` (example CIDR)
  * DNS hostnames enabled
  * DNS support enabled

#### Subnets

* **Public Subnets**
  * `10.3.1.0/24` (Availability Zone A)
  * `10.3.3.0/24` (Availability Zone B)
  * Tagged for ELB: `kubernetes.io/role/elb = 1`
* **Private Subnets**
  * `10.3.2.0/24` (Availability Zone A)
  * `10.3.4.0/24` (Availability Zone B)
  * Tagged for internal ELB: `kubernetes.io/role/internal-elb = 1`

#### Networking Components

* **Internet Gateway** (IGW)
* **NAT Gateway** (Single NAT Gateway for cost optimization)
* **Route Tables** (Public and Private)
* **VPC Endpoints** (for private access to AWS services):
  * ECR API Endpoint (`com.amazonaws.{region}.ecr.api`)
  * ECR DKR Endpoint (`com.amazonaws.{region}.ecr.dkr`)
  * CloudWatch Logs Endpoint (`com.amazonaws.{region}.logs`)
  * EventBridge Endpoint (`com.amazonaws.{region}.events`) - Optional
  * S3 Gateway Endpoint (`com.amazonaws.{region}.s3`)
  * SageMaker Runtime Endpoint (`com.amazonaws.{region}.sagemaker.runtime`)
  * SageMaker API Endpoint (`com.amazonaws.{region}.sagemaker.api`)

#### Security Groups

* **EKS Cluster Security Group**
* **Node Security Groups** (for each node group)
* **SageMaker Endpoint Security Group**
* **VPC Endpoint Security Group**

***

### EKS Cluster & Node Groups

#### EKS Cluster

* **Cluster Name**: `example-cluster` (example name, will be set from config.ini)
* **Kubernetes Version**: Latest supported
* **CloudWatch Logging**: Enabled (14-day retention)
* **Public Endpoint Access**: Enabled

#### Node Groups

**1. Private Node Group**

* **Instance Types**: `t3.medium`
* **Desired Size**: 2
* **Min Size**: 2
* **Max Size**: 3
* **Subnets**: Private subnets
* **Capacity Type**: ON\_DEMAND
* **Workload Type**: Private workloads
* **Labels**: `workload-type=private`
* **Services**: Backend application, Monitoring services (Grafana, Prometheus, Loki)

**2. Database Node Group**

* **Instance Types**: `t3.xlarge`
* **Desired Size**: 2
* **Min Size**: 2
* **Max Size**: 5
* **Subnets**: Private subnets
* **Disk Size**: 400GB (gp3, encrypted)
* **Workload Type**: Database workloads
* **Labels**: `workload-type=database`

**3. Public Node Group (Disabled)**

* **Status**: Disabled (desired\_size = 0)
* **Note**: Public node group is not created. All workloads run on private nodes.

**4. MCP Node Group**

* **Instance Types**: `t3.xlarge`
* **Desired Size**: 2
* **Min Size**: 2
* **Max Size**: 4
* **Subnets**: Private subnets
* **Capacity Type**: ON\_DEMAND
* **Workload Type**: MCP workloads
* **Labels**: `workload-type=mcp`
* **Services**: MCP Server, MCP Agent, Code Optim Agent

#### EKS Add-ons

* **EBS CSI Driver** (for persistent volumes)
* **AWS Load Balancer Controller**
* **CoreDNS** (for service discovery)
* **kube-proxy**
* **VPC CNI**

***

### Kubernetes Resources

#### Namespaces

* **backend** - Backend application namespace
* **frontend** - Frontend application namespace
* **db** - Database namespace (PostgreSQL)
* **neo4j** - Neo4j database namespace
* **lambda** - Lambda functions namespace
* **mcp** - MCP services namespace (MCP Server, MCP Agent, Code Optim Agent)
* **monitoring** - Monitoring stack namespace (Grafana, Prometheus)
* **logging** - Logging stack namespace (Loki, Fluent-bit)

#### Helm Charts Deployed

**1. Backend (`charts/backend/`)**

* **Deployment**: Backend application pods
* **Service**: ClusterIP service for backend
* **Service (LB)**: LoadBalancer service for backend
* **Ingress**: ALB Ingress for external access
* **HPA**: Horizontal Pod Autoscaler
* **Image**: `loci-backend:latest`

**2. Frontend (`charts/frontend/`)**

* **Deployment**: Frontend application pods
* **NodeSelector**: `workload-type: private` (explicitly configured - runs on Private Node Group)
* **Service**: ClusterIP service for frontend
* **Ingress**: ALB Ingress for external access
* **Image**: `example-frontend:latest` (example image name)
* **Hostname**: `example.com` (example hostname, will be set from config.ini)

**3. Neo4j (`charts/neo4j/`)**

* **Helm Chart**: Neo4j Community Edition
* **Deployment**: Neo4j database pods
* **NodeSelector**: `workload-type: database` (explicitly configured - runs on Database Node Group)
* **Service**: ClusterIP and LoadBalancer services
* **Backup CronJob**: Automated Neo4j backups to S3
* **Credentials**: Managed via Kubernetes secrets

**4. PostgreSQL (`charts/postgres-pgo/`)**

* **PostgreSQL Operator**: PGO (PostgreSQL Operator)
* **PostgreSQL Cluster**: High Availability PostgreSQL
* **NodeSelector**: `workload-type: database` (explicitly configured - runs on Database Node Group)
* **Service**: `loci-postgres-ha` service
* **Backup CronJob**: Automated PostgreSQL backups to S3
* **Credentials**: Managed via Kubernetes secrets

**5. Grafana (`charts/grafana/`)**

* **Helm Chart**: Grafana
* **Namespace**: `monitoring`
* **Deployment**: Grafana pods
* **NodeSelector**: None (can run on any node group)
* **Service**: ClusterIP service
* **Ingress**: ALB Ingress for external access
* **Hostname**: `grafana.example.com` (example hostname, will be set from config.ini)
* **Storage**: 10Gi persistent volume
* **Dashboards**: Pre-configured dashboards (cluster-logs.json)
* **Data Sources**: Prometheus, Loki

**6. Prometheus (`charts/prometheus/`)**

* **Helm Chart**: Prometheus
* **Namespace**: `monitoring`
* **Deployment**: Prometheus pods
* **NodeSelector**: `workload-type: private` (explicitly configured - runs on Private Node Group)
* **Service**: ClusterIP service (`prometheus.monitoring.svc.cluster.local:9090`)
* **Storage**: 50Gi persistent volume
* **Retention**: 7 days
* **Scraping**: Metrics collection from cluster

**7. Loki (`charts/loki/`)**

* **Helm Chart**: Loki
* **Namespace**: `logging`
* **Deployment**: Loki pods (SingleBinary mode)
* **NodeSelector**: `workload-type: private` (explicitly configured - runs on Private Node Group)
* **Service**: ClusterIP service (`loci-logs-loki.logging.svc.cluster.local:3100`)
* **Storage**: 50Gi persistent volume
* **Retention**: 48 hours (2 days)
* **External Service**: For Fluent-bit integration

**8. Fluent-bit (`charts/fluent-bit/`)**

* **DaemonSet**: Fluent-bit pods
* **Namespace**: `logging`
* **NodeSelector**: `workload-type: private` (explicitly configured - runs on all Private Node Group nodes)
* **Log Forwarding**: To Loki and CloudWatch

**8. Fluent-bit (`charts/fluent-bit/`)**

* **DaemonSet**: Fluent-bit pods on all nodes
* **ConfigMap**: Fluent-bit configuration
* **ServiceAccount**: With IRSA for CloudWatch access
* **ClusterRole**: Permissions for log collection
* **Log Forwarding**: To Loki and CloudWatch

**9. Lambda (`charts/lambda/`)**

* **Kubernetes Functions**: Lambda functions deployed as K8s resources
* **RBAC**: ServiceAccount and RoleBindings
* **Functions**:
  * Version Uploaded Lambda
  * Service Status Updated Lambda
  * SageMaker Status Lambda

**10. MCP Server (`charts/mcp/mcp-server/`)**

* **Helm Chart**: MCP Server
* **Namespace**: `mcp`
* **Deployment**: MCP Server pods
* **NodeSelector**: `workload-type: mcp` (explicitly configured - runs on MCP Node Group)
* **Service**: ClusterIP service (`loci-mcp-server.mcp.svc.cluster.local:7000`)
* **Image**: `loci-mcp-server:latest`
* **Resources**: 1 CPU limit, 3Gi memory limit
* **Environment**: Backend URL configured

**11. MCP Agent (`charts/mcp/mcp-agent/`)**

* **Helm Chart**: MCP Agent
* **Namespace**: `mcp`
* **Deployment**: MCP Agent pods
* **NodeSelector**: `workload-type: mcp` (explicitly configured - runs on MCP Node Group)
* **Service**: ClusterIP service (port 8000)
* **Ingress**: ALB Ingress for external access
* **Hostname**: `agent.example.com` (example hostname, will be set from config.ini)
* **Image**: `example-mcp-agent:latest` (example image name)
* **Resources**: 2 CPU limit, 3Gi memory limit
* **Environment**: Backend URL and AWS credentials configured
* **MCP Server URL**: `example-mcp-server.mcp.svc.cluster.local` (example service name)

***

### AWS Services

#### ECS (Elastic Container Service)

* **ECS Cluster**: `LociPlatform{LociEnv}Cluster`
* **Capacity Providers**: FARGATE, FARGATE\_SPOT
* **Task Definitions**:
  * **Static Analysis Task**: `LociPlatform{LociEnv}StaticAnalysis`
    * CPU: 8192 (8 vCPU)
    * Memory: 61440 MB (60 GB)
    * Container: `static-analysis`
  * **LCLM Task**: `LociPlatform{LociEnv}LCLM`
    * CPU: 8192 (8 vCPU)
    * Memory: 61440 MB (60 GB)
    * Container: `lclm`

#### SageMaker

* **SageMaker Model**: `LociPlatform{LociEnv}Model`
  * Model Package ARN: From config (`lclm-multi`)
  * VPC Configuration: Enabled
* **Endpoint Configuration**: `LociPlatform{LociEnv}EndpointConfig`
  * Instance Type: `ml.g5.xlarge`
  * Async Inference: Enabled
  * SNS Notifications: Configured
* **SageMaker Endpoint**: `LociPlatform{LociEnv}Endpoint`
  * Auto Scaling: Enabled (min: 1, max: configured)
  * CloudWatch Alarms: CPU and Memory utilization

#### DynamoDB

* **Table**: `LociPlatform{LociEnv}PipelineDB`
  * Billing Mode: PAY\_PER\_REQUEST
  * Primary Key: `version_id` (Hash), `artifact_action` (Range)
  * Point-in-Time Recovery: Enabled
  * Encryption: Server-side encryption enabled

#### S3 Buckets

* **Storage Bucket**: `loci-{environment}` (or configured name)
  * Versioning: Suspended
  * Encryption: AES256
  * Public Access: Blocked
  * Lifecycle Rules: Transition to IA (30 days), Glacier (90 days)
* **Backup Bucket**: `loci-backups-{environment}`
  * Used for: PostgreSQL backups, Neo4j backups
* **Terraform State Bucket**: `loci-terraform` (or configured)
  * State file: `cluster/terraform.tfstate`

#### EventBridge

* **Event Bus**: `LociPlatform{LociEnv}Events`
* **Event Rules**:
  * `LociPlatform{LociEnv}PipelineStarted`
  * `LociPlatform{LociEnv}PipelineCompleted`
  * `LociPlatform{LociEnv}PipelineFailed`
  * `LociPlatform{LociEnv}VersionUploaded`
  * `LociPlatform{LociEnv}ServiceStatusUpdated`

#### SNS (Simple Notification Service)

* **Topic**: `LociPlatform{LociEnv}Notifications`
  * Used for: SageMaker async inference notifications
  * Used for: Pipeline event notifications

#### CloudWatch

* **Log Groups**:
  * `/ecs/LociPlatform{LociEnv}StaticAnalysis` (14-day retention)
  * `/ecs/LociPlatform{LociEnv}LCLM` (14-day retention)
  * `/aws/sagemaker/Endpoints/LociPlatform{LociEnv}Endpoint` (14-day retention)
  * `/aws/lambda/LociPlatform{LociEnv}-VersionUploadedLambda` (14-day retention)
  * `/aws/lambda/LociPlatform{LociEnv}-ServiceStatusUpdatedLambda` (14-day retention)
  * `/aws/lambda/LociPlatform{LociEnv}-SageMakerStatusLambda` (14-day retention)
* **Alarms**:
  * SageMaker High CPU Utilization
  * SageMaker High Memory Utilization

#### Lambda Functions (Kubernetes-based)

* **Version Uploaded Lambda**: Handles S3 upload events
* **Service Status Updated Lambda**: Handles ECS task status updates
* **SageMaker Status Lambda**: Handles SageMaker endpoint status

***

### Route53 & DNS

#### Public DNS (Route53 Hosted Zone)

* **Hosted Zone**: `example.com` (example zone ID: Z08012303MU06OUHG8U2M)
* **Records Created**:
  * `example.com` → Frontend ALB (example hostname)
  * `api.example.com` → Backend ALB (example hostname)
  * `grafana.example.com` → Grafana ALB (example hostname)
  * `agent.example.com` → MCP Agent ALB (example hostname)

#### Private DNS (Route53 Private Hosted Zone)

* **Private Zone**: `k8s.{environment}.internal`
* **VPC Association**: Associated with VPC
* **Service Discovery Records**:
  * `neo4j.k8s.{environment}.internal` → Neo4j LoadBalancer
  * `loci-postgres-ha.k8s.{environment}.internal` → PostgreSQL LoadBalancer
  * `loci-backend.k8s.{environment}.internal` → Backend LoadBalancer

#### Route53 Resolver

* **Resolver Endpoint**: `{environment}-k8s-dns-forwarder` (OUTBOUND)
* **Resolver Rule**: `{environment}-k8s-service-forwarding`
  * Forwards `svc.cluster.local` queries to CoreDNS
* **Rule Association**: Associated with VPC

***

### Monitoring & Logging

#### Prometheus

* **Metrics Collection**: Cluster-wide metrics
* **Scraping Targets**: All Kubernetes services
* **Storage**: Persistent volume

#### Grafana

* **Dashboards**: Pre-configured dashboards
  * Cluster Logs Dashboard
* **Data Sources**: Prometheus, Loki
* **Access**: `https://grafana.example.com` (example URL, will be set from config.ini)

#### Loki

* **Log Aggregation**: Centralized log storage
* **Service**: `loci-logs-loki.logging.svc.cluster.local`
* **Integration**: Fluent-bit → Loki

#### Fluent-bit

* **Log Collection**: DaemonSet on all nodes
* **Log Forwarding**:
  * To Loki (cluster logs)
  * To CloudWatch (AWS service logs)
* **Filters**: Log parsing and enrichment

#### CloudWatch

* **Container Insights**: Enabled on ECS cluster
* **Log Groups**: All application and service logs
* **Metrics**: ECS, SageMaker, Lambda metrics

***

### Security & IAM

#### IAM Roles

**ECS Roles**

* **ECS Task Execution Role**: `LociPlatform{LociEnv}ECSTaskExecutionRole`
  * ECR access
  * CloudWatch Logs access
  * S3 read access (model artifacts)
* **ECS Task Role**: `LociPlatform{LociEnv}ECSTaskRole`
  * Full S3 access
  * EventBridge access
  * DynamoDB access
  * SageMaker access
  * ECS access
  * SNS access
  * CloudWatch Logs access

**SageMaker Roles**

* **SageMaker Execution Role**: `LociPlatform{LociEnv}SageMakerExecutionRole`
  * SageMaker Full Access
  * S3 access (storage bucket)
  * SNS access (notifications)
  * ECR access (cross-account)
  * Model Package access (cross-account)

**Lambda Roles**

* **Lambda Execution Roles**: Created via Kubernetes IRSA
  * ECS access
  * S3 access
  * EventBridge access
  * DynamoDB access
  * SageMaker access

**Kubernetes Service Accounts**

* **lambda-secret-updater**: ServiceAccount with IRSA
  * Updates Kubernetes secrets from AWS Secrets Manager
* **fluent-bit**: ServiceAccount with IRSA
  * CloudWatch Logs write access

#### IAM Policies

* **DynamoDB Pipeline Access Policy**: `LociPlatform{LociEnv}DynamoDBAccess`
* **SageMaker S3 Access Policy**: `LociPlatform{LociEnv}SageMakerS3Access`
* **SageMaker SNS Access Policy**: `LociPlatform{LociEnv}SageMakerSNSAccess`
* **SageMaker Model Package Access Policy**: `LociPlatform{LociEnv}SageMakerModelPackageAccess`
* **SageMaker ECR Access Policy**: `LociPlatform{LociEnv}SageMakerECRAccess`

#### Security Groups

* **EKS Cluster Security Group**: Cluster control plane access
* **Node Security Groups**: Node group access rules
* **SageMaker Endpoint Security Group**: Endpoint access (HTTPS from VPC)
* **VPC Endpoint Security Group**: VPC endpoint access (HTTPS from VPC)

#### Secrets Management

* **Kubernetes Secrets**:
  * Neo4j credentials (`neo4j` namespace)
  * PostgreSQL credentials (`db` namespace)
  * Lambda environment variables (`lambda` namespace)
  * AWS credentials (`mcp` namespace) - Used by MCP Agent and Code Optim Agent
* **AWS Secrets Manager**: (if configured)
  * Database passwords
  * API keys

***

### Storage

#### EBS Volumes

* **Database Node Volumes**: 400GB gp3 encrypted volumes
* **Persistent Volumes**: Created via EBS CSI Driver
  * PostgreSQL data volumes
  * Neo4j data volumes
  * Prometheus storage

#### S3 Storage

* **Application Data**: `loci-{environment}` bucket
  * Model artifacts
  * SageMaker input/output
  * Application uploads
* **Backups**: `loci-backups-{environment}` bucket
  * PostgreSQL backups (pgBackRest)
  * Neo4j backups
* **Terraform State**: `loci-terraform` bucket
  * Infrastructure state files

#### Storage Classes (Kubernetes)

* **gp3**: General purpose SSD (default)
* **io1**: Provisioned IOPS SSD (if configured)

***

### Summary

#### Total Resource Count (Approximate)

* **VPC Resources**: \~15 (VPC, subnets, gateways, route tables, endpoints)
* **EKS Resources**: 1 cluster + 3 node groups (Private + Database + MCP; Public disabled)
* **Kubernetes Namespaces**: 8 (backend, frontend, db, neo4j, lambda, mcp, monitoring, logging)
* **Helm Charts**: 12
* **ECS Resources**: 1 cluster + 2 task definitions
* **SageMaker Resources**: 1 model + 1 endpoint config + 1 endpoint
* **DynamoDB Tables**: 1
* **S3 Buckets**: 2-3
* **Route53 Zones**: 2 (1 public + 1 private)
* **Route53 Records**: \~8-10
* **IAM Roles**: \~5-7
* **IAM Policies**: \~8-10
* **Security Groups**: \~5-7
* **CloudWatch Log Groups**: \~6
* **CloudWatch Alarms**: 2
* **EventBridge Resources**: 1 event bus + 5 rules
* **SNS Topics**: 1
* **Lambda Functions**: 3 (Kubernetes-based)

***

### Node Group Assignments

#### Services by Node Group

**Private Node Group (`workload-type: private`)**

* **Backend** (`backend` namespace)
  * Application pods
  * NodeSelector: `workload-type: private` (explicitly configured)
  * Service: `loci-backend`
  * LoadBalancer: Internal NLB for backend access
* **Frontend** (`frontend` namespace)
  * Application pods
  * NodeSelector: `workload-type: private` (explicitly configured)
  * Service: Frontend service
  * Ingress: ALB for external access
* **Prometheus** (`monitoring` namespace)
  * Prometheus pods
  * NodeSelector: `workload-type: private` (explicitly configured)
  * Storage: 50Gi persistent volume
  * Service: ClusterIP (`prometheus.monitoring.svc.cluster.local:9090`)
* **Loki** (`logging` namespace)
  * Loki pods
  * NodeSelector: `workload-type: private` (explicitly configured)
  * Storage: 50Gi persistent volume
  * Service: ClusterIP (`loci-logs-loki.logging.svc.cluster.local:3100`)
* **Fluent-bit** (`logging` namespace)
  * DaemonSet pods (runs on all private nodes)
  * NodeSelector: `workload-type: private` (explicitly configured)
  * Log collection from all nodes

**Database Node Group (`workload-type: database`)**

* **Neo4j** (`neo4j` namespace)
  * Neo4j database pods
  * NodeSelector: `workload-type: database` (explicitly configured)
  * Storage: 120Gi EBS volumes
  * Service: `neo4j` (ClusterIP) + LoadBalancer (Internal NLB)
* **PostgreSQL** (`db` namespace)
  * PostgreSQL cluster pods (managed by PGO)
  * NodeSelector: `workload-type: database` (explicitly configured)
  * Replicas: 2 instances
  * Storage: 400Gi EBS volumes per instance
  * Service: `loci-postgres-ha` (LoadBalancer - Internal NLB)
  * PGO Operator: Deployed in `db` namespace (no nodeSelector - control plane component)

**MCP Node Group (`workload-type: mcp`)**

* **MCP Server** (`mcp` namespace)
  * MCP Server pods
  * NodeSelector: `workload-type: mcp` (explicitly configured)
  * Service: `loci-mcp-server` (ClusterIP)
  * Resources: 1 CPU, 3Gi memory
* **MCP Agent** (`mcp` namespace)
  * MCP Agent pods
  * NodeSelector: `workload-type: mcp` (explicitly configured)
  * Service: ClusterIP + Ingress (ALB)
  * Hostname: `agent.example.com` (example hostname)
  * Resources: 2 CPU, 3Gi memory

**Public Node Group (`workload-type: public`) - DISABLED**

* **Status**: Not created (disabled in configuration)
* **Note**: Public node group is disabled. System pods (CoreDNS, kube-proxy, ALB Ingress Controller) will run on private nodes.

**All Node Groups**

* **Fluent-bit** (`logging` namespace)
  * DaemonSet deployed on all nodes
  * No nodeSelector (runs on all node types)
  * Collects logs from all nodes

#### Node Group Summary

* **Public Node Group**: **DISABLED** (not created)
* **Private Node Group**: All workloads run here (applications + system pods):
  * Backend (explicitly configured with `workload-type: private`)
  * Frontend (explicitly configured with `workload-type: private`)
  * Prometheus (explicitly configured with `workload-type: private`)
  * Loki (explicitly configured with `workload-type: private`)
  * Fluent-bit DaemonSet (explicitly configured with `workload-type: private`)
  * **Min Size: 2 nodes**
* **Database Node Group**: Database workloads only:
  * Neo4j (explicitly configured with `workload-type: database`)
  * PostgreSQL (explicitly configured with `workload-type: database`)
  * **Min Size: 2 nodes**
* **MCP Node Group**: MCP/AI workloads:
  * MCP Server (explicitly configured with `workload-type: mcp`)
  * MCP Agent (explicitly configured with `workload-type: mcp`)
  * Code Optim Agent (explicitly configured with `workload-type: mcp`)
  * **Min Size: 2 nodes**
  * **Instance Type**: `t3.xlarge` (4 vCPU, 16GB RAM)

#### Monitoring Services Details

* **Namespace**: `monitoring` (Grafana, Prometheus) and `logging` (Loki, Fluent-bit)
* **Node Assignment**:
  * **Prometheus**: Explicitly configured with `workload-type: private` - runs on Private Node Group
  * **Loki**: Explicitly configured with `workload-type: private` - runs on Private Node Group
  * **Fluent-bit**: Explicitly configured with `workload-type: private` - DaemonSet runs on all Private Node Group nodes
  * **Grafana**: No explicit nodeSelector (can run on any node group, typically scheduled on Private Node Group)
* **Storage**: All monitoring services use persistent volumes (Grafana: 10Gi, Prometheus: 50Gi, Loki: 50Gi)

***


