# Human-Centric System Intelligence: Practical Plan

**Date:** June 2026
**Status:** Draft
**Trigger:** The assimilation crisis — AI generates code faster than humans can understand it.

---

## The Problem

AI generates code at scale. Humans approve it. But humans can't hold the system in their heads.

This isn't technical debt — it's **codebase cognitive debt**: the gap between what a system does and what any human understands about it. It lives in minds, not in code. A team crippled by cognitive debt hesitates to change things. They treat the system as a fragile black box. They rely on the one senior engineer who knows how it all fits.

This gets worse with multiple repos. No human thinks in repos. They think in systems: *"A user clicks checkout — what happens? Which services? Which teams? What breaks if payments go down?"*

Today that answer lives in a senior engineer's head, a stale Confluence page, or a Slack thread nobody can find.

**Sruja's job: compress that answer from 3 days of asking around into 3 seconds of running a command.**

---

## The Shift: Scan-First, Not DSL-First

Today Sruja asks humans to write `.sruja` files describing their architecture. This creates an adoption barrier: before you get value, you must author and maintain a DSL file. For a single repo this is manageable. For 50 repos across an organization, it's unrealistic.

**The new model:**

| | Old model (DSL-first) | New model (scan-first) |
|---|---|---|
| Architecture source | Human authors `.sruja` files | Scanner discovers from code |
| Human contribution | Everything: structure + intent | Only what scanner can't know: intent, policies, gotchas |
| Value at install | Zero — must author DSL first | Immediate — `sruja scan` gives you a graph |
| Enforcement | Needs full DSL | Works with scan + optional policies |
| Cross-repo | Requires DSL in every repo | Works from scans alone, DSL where available |

**The scanner already finds 80% of the architecture.** Containers, components, services, databases, APIs, dependencies, technologies — all auto-discovered from source code, package manifests, OpenAPI specs, Docker configs, and import analysis.

The `.sruja` file doesn't disappear. It becomes **thinner** — only what requires human judgment:

```sruja
// Auto-generated by sruja init — do not edit structure section
// Edit only: policies, gotchas, constraints, ownership below

PaymentService = container "Payment Service" {
  technology "Rust"          // ← auto-detected
  criticality HIGH           // ← human intent
  owner "@fintech"           // ← human intent

  gotcha "FraudService has no fallback. If it's down, payments fail."
  constraint "Only CartService and WebhookHandler may call PaymentService directly"
  constraint "Must NOT access OrdersDB directly"
}

boundary payments_isolation {
  from PaymentService
  to [OrdersDB]
  allowed false
  reason "Payment must not directly access order data — use OrderService API"
}

decision ADR_012 {
  title "Synchronous fraud check"
  status accepted
  file "docs/adr/012-sync-fraud-check.md"
  affects [PaymentService, FraudService]
}
```

**Adoption path:**
1. `sruja init` → auto-discovers architecture from code (zero human effort, immediate value)
2. `sruja human trace`, `sruja human explain`, `sruja human map` → human gets system understanding
3. Optionally add policies, gotchas, boundaries → enforcement layer activates
4. `sruja drift` → catches when code violates declared policies

Value from day 1. Enforcement when the team is ready. No upfront DSL authoring required.

---

## What Sruja Already Has

| Capability | Status | Notes |
|---|---|---|
| Architecture scanner (13 languages) | Production | Tree-sitter + manifests + SCIP |
| Single-repo graph (scan + DSL) | Production | Nodes, edges, centrality, communities |
| Architecture enforcement (lint, drift, boundaries) | Production | Works, but requires DSL |
| Federation (publish/compose) | Built but disconnected | Merges bundles, but no cross-repo traversal |
| MCP server (50+ tools) | Production | Single-repo only, unaware of system index |
| VS Code extension | Production | DSL-focused, not system-focused |
| Cross-repo system index | Data structure only | Nodes/edges merged, not traversable |
| Embedding-based semantic search | Module exists, not wired | `vector.rs` in sruja-export |
| `sruja explain` command | Referenced, not implemented | — |
| Cross-repo blast radius | Not implemented | — |
| Cross-repo edge inference | Not implemented | Fields exist (`logical_id`, `aliases`) but unused |
| Human narrative output | Not implemented | `--enrich` exists but disconnected |

**The core gap:** Sruja can *merge* cross-repo graphs but cannot *reason* across them. Every consumer (focus, why, context, query, explain) operates on a single repo. The system index is a static JSON file nobody reads.

---

## Guiding Principles

1. **Zero-friction start.** `sruja init` gives you value. No DSL authoring, no setup wizard, no config files.
2. **Human questions, not graph queries.** "What happens when a user checks out?" not "traverse BFS from node X depth 3."
3. **Compass, not encyclopedia.** ~1,000 tokens of compressed understanding per module (Meta's research: 40% reduction in exploration cost). Never dump raw data.
4. **Situation model, not program model.** Humans easily learn *what* code does. They struggle with *why* it exists. Optimize for the why: decisions, rationale, boundaries, ownership, gotchas.
5. **Scan is truth, DSL is intent.** The scanner discovers reality. The DSL captures intent. Drift between them is the most valuable signal in the system.
6. **Multi-repo is the default.** Single-repo is a special case. Humans think in systems, not repos.
7. **LLM is a premium rendering layer, never a required dependency.** Every feature works without an LLM. LLM calls are opt-in, cost-aware, and always grounded in deterministic facts.

---

## LLM Cost Strategy

Sruja's value comes from the deterministic graph — the scanner, the traversal engine, the architecture model. An LLM is only needed to *polish* the output into human-friendly narratives. This means LLM costs should be near-zero by default and only incurred when a human explicitly asks for richer output.

### The Cost Hierarchy

```
Free (deterministic, no LLM)           $0.00
  ├─ sruja scan                         tree-sitter + manifests
  ├─ sruja human map                          graph layout + ASCII render
  ├─ sruja human trace                        graph traversal + template render
  ├─ sruja human explain                      template render from graph data
  ├─ sruja human before                       blast radius + template render
  ├─ sruja human daily                        diff detection + template render
  ├─ sruja human cognitive-debt               metric computation (all math)
  └─ sruja drift / lint / classify      deterministic rules

Near-Free (local embeddings, no API)    ~$0.00
  ├─ Entity resolution ("payment")      fastembed BGE-small (local, ONNX)
  ├─ Semantic search                    cosine similarity (local)
  ├─ Cross-repo edge matching           embedding similarity (local)
  └─ Query routing                      heuristic classifier (existing)

Cheap (small model, ~$0.001/call)
  ├─ Entity resolution (fuzzy)          Haiku/Flash for borderline cases
  ├─ Narrative polish (--enrich)         Haiku/Flash for template → prose
  └─ Non-Rust classification            Haiku/Flash for crate tier inference

Moderate (large model, ~$0.01-0.05/call)
  ├─ sruja human what-if risk narrative       Sonnet for nuanced risk reasoning
  └─ sruja human explain --enrich             Sonnet for rich situation model
```

### Cost Architecture

#### 1. Never Call an LLM by Default

Every command works perfectly with template rendering. The `--enrich` flag (which already exists) is the only trigger for LLM calls. This is already the case today — keep it that way.

| Command | Default (free) | With `--enrich` (LLM) |
|---|---|---|
| `sruja human trace "..."` | Template flow diagram | Polished narrative flow |
| `sruja human explain X` | Structured template output | Rich human-readable prose |
| `sruja human map` | ASCII diagram | Polished system overview |
| `sruja human before` | Impact template | Nuanced risk assessment |
| `sruja human what-if "..."` | Blast radius + facts | Risk narrative with reasoning |
| `sruja cognitive-debt` | Metric scores + template | Prioritized recommendations |

**Target: 95% of usage is free. 5% uses LLM.**

#### 2. Local Embeddings First, LLM Only for Borderline

Entity resolution (matching "how does payment work" to `PaymentService`) uses a cascade:

```
Step 1: Exact match (free)           "PaymentService" → exact hit
Step 2: Keyword match (free)         "payment" → substring hit
Step 3: Embedding similarity (local) "how does checkout work" → cosine top-k
Step 4: LLM disambiguate (cheap)     "the fraud thing" → Haiku picks from top-3
```

Steps 1-3 cost nothing. Step 4 only fires when the user's query is genuinely ambiguous and the embedding matches multiple candidates with similar scores.

The existing `fastembed` (BGE-small-en-v1.5) is already a dependency. It runs locally via ONNX — no API call, no cost. Wire it into `trace` and `explain` entity resolution (W3.3 in the plan).

#### 3. Prompt Caching for Enrichment

When `--enrich` is used, structure the API call for maximum cache hits:

Sruja already has cache-friendly context (`build_cache_friendly_task_export()` in `logic.rs:1590`). Extend this pattern to enrichment:

```
[Cached prefix — static per repo, ~2K tokens]
  System prompt + grounding instruction
  + repo classification + architecture boundaries
  + element definitions + ownership

[Dynamic suffix — per query, ~500 tokens]
  Specific element data for this query
  + "Produce markdown explaining this element"
```

Anthropic caches at 90% discount. OpenAI at 50%. With a ~2K token cached prefix, a `sruja human explain --enrich` call costs:
- Anthropic: $0.003 (cached read) + $0.015 (new output) = **~$0.02**
- OpenAI: $0.005 (cached) + $0.015 (output) = **~$0.02**
- Without caching: ~$0.05

**~60% cost reduction with zero code complexity — just structured prompts.**

Implementation: Extend `enrichment.rs` to send the repo's architecture invariant block as the first message (cached), and the per-element data as the second message (dynamic).

```
File: crates/sruja-cli/src/enrichment.rs (extend, ~50 lines)
```

#### 4. Small Model Routing

Not every enrichment needs Sonnet. Route by task complexity:

| Task | Model | Cost/call | Why |
|---|---|---|---|
| Entity disambiguation | Haiku / Flash | $0.001 | Pick from 3 options — trivial |
| Template → prose polish | Haiku / Flash | $0.002 | Constrained output, grounded facts |
| Risk narrative (what-if) | Sonnet | $0.02 | Needs nuanced reasoning |
| Rich explain narrative | Sonnet | $0.02 | Needs deep comprehension |

Configuration in `.sruja/config.toml`:

```toml
[enrichment]
default_model = "auto"    # auto = route by task
cheap_model = "claude-haiku-4-0-20250514"  # or "gpt-4o-mini"
premium_model = "claude-sonnet-4-20250514"  # or "gpt-4o"
```

When `default_model = "auto"`, Sruja decides. When set to a specific model, all enrichment uses that model. Default: `auto`.

#### 5. Batch Processing for Bulk Operations

When an org first adopts Sruja across 50 repos:

- Initial scan + classification: batch API (50% discount, 1-6h latency, acceptable for one-time setup)
- Narrative generation for all services: batch API
- Ongoing daily use: real-time API (user is waiting)

```
File: crates/sruja-cli/src/integrations/batch.rs (new ~200 lines)
```

**Cost comparison for 50-repo initial setup:**

| Approach | Cost |
|---|---|
| Sonnet for everything, real-time | ~$25 |
| Batch API + Haiku routing | ~$2.50 |
| Local embeddings only (no narratives) | **$0** |

#### 6. Cost Dashboard

Humans should see what they're spending:

```bash
$ sruja costs

── LLM Usage (last 30 days) ──

API calls: 47 (all --enrich)
  Haiku: 32 × $0.002 = $0.06
  Sonnet: 15 × $0.02 = $0.30

Total: $0.36
Free operations: 892 (scan, trace, explain, map, daily, drift)

Most expensive command: sruja human explain PaymentService --enrich ($0.02)
```

Track in `.sruja/usage.jsonl` — append-only log of LLM calls with model, tokens, cost.

```
File: crates/sruja-cli/src/integrations/usage.rs (new ~150 lines)
File: crates/sruja-cli/src/commands/costs.rs (new ~100 lines)
```

### Cost Targets

| Scenario | Target cost | How |
|---|---|---|
| Daily engineer usage (no enrich) | **$0/month** | All deterministic |
| Daily engineer usage (with enrich) | **< $2/month** | Prompt caching + small model routing |
| Team of 10, mixed usage | **< $15/month** | 90% free + cheap enrichment |
| Org onboarding (50 repos) | **< $5 one-time** | Batch API + local embeddings |
| CI pipeline (drift + cognitive-debt) | **$0** | All deterministic |

---

## The Plan

### Phase 0: Scan-First Foundation (3 weeks)

**Goal:** Make `sruja init` produce a usable system graph from code alone. Make the system index traversable.

---

#### W0.1: `sruja init` Becomes Scan-First

Today `sruja init` sets up an empty `.sruja/` directory and expects humans to write DSL. Change it to:

1. Run `scan_repo()` — discovers containers, services, databases, APIs, dependencies.
2. Generate `.sruja/scan.json` — the auto-discovered architecture graph.
3. Generate a starter `repo.sruja` from the scan — structure section is auto-populated and marked `// auto-generated, do not edit`. Intent section is empty with comments prompting human to add policies, gotchas, ownership.
4. Generate `.sruja/classification.json` from scan (layers, boundaries inferred from crate/module structure).

**Result:** After `sruja init`, you immediately get `sruja map`, `sruja trace`, `sruja explain` working — without writing a single line of DSL.

```
File: crates/sruja-cli/src/commands/init.rs (rewrite, ~300 lines)
File: crates/sruja-scan/src/graph/mod.rs (add to_dsl() method, ~200 lines)
```

**Validation:** Run `sruja init` on Sruja's own repo. Verify it discovers all 14 crates, their dependencies, and generates a valid starter repo.sruja.

---

#### W0.2: Traversable SystemGraph

The `system.index.json` from federation is a static data structure. Turn it into a traversable graph.

Create `SystemGraph` that wraps the composed system index with traversal methods:

- `neighbors(id, direction)` — follow edges in/out, crossing repo boundaries
- `blast_radius(id, depth)` — transitive impact across repos
- `find_path(a, b)` — shortest path between any two elements in any repo
- `entrypoints()` — external-facing APIs and frontends across all repos
- `data_stores()` — all databases, queues, caches across the system
- `hubs()` — elements with high betweenness centrality (cross-repo choke points)
- `teams()` — group elements by ownership

Support both DSL-derived and scan-derived edges. DSL edges win on confidence.

```
File: crates/sruja-graph/src/system_graph.rs (new ~500 lines)
Extends: sruja-graph-core traits
```

**Validation:** Publish 3 test repos → compose → `system_graph.blast_radius("repoA::Service")` returns elements from all 3 repos.

---

#### W0.3: Cross-Repo Edge Inference

Today `compose()` only merges intra-repo edges. Add a second pass that infers inter-repo relationships — **all deterministic, no LLM needed**:

- **Config matching:** repoA's Docker Compose references `http://cart-service:8080` → match to repoB's `CartService` exposing port 8080. Confidence: HIGH.
- **API matching:** repoA's OpenAPI client references `POST /api/checkout` → match to repoB's OpenAPI server exposing that endpoint. Confidence: HIGH.
- **Name similarity:** repoA imports `@company/cart-service` → repoB is named `cart-service`. Confidence: MEDIUM.
- **Embedding similarity (local):** service names embedded via fastembed → cosine match across repos. Confidence: MEDIUM. Falls back to name similarity.
- **Technology heuristic:** repoA publishes to Kafka topic `payment-events` → repoB subscribes to `payment-events`. Confidence: MEDIUM.

Use the existing `logical_id` and `aliases` fields (already on `SystemIndexNode`, currently unused) for entity resolution. Tag every inferred edge with confidence level. Low-confidence edges appear in output but are clearly marked as `inferred (low confidence)`.

**Cost: $0 — all local computation (string matching + fastembed).**

```
File: crates/sruja-cli/src/commands/federation.rs (extend compose(), ~250 lines new)
File: crates/sruja-export/src/vector.rs (extend for cross-repo matching, ~50 lines)
```

**Validation:** Compose 3 repos where repoA calls repoB's API (via Docker Compose reference) and repoB publishes to Kafka that repoC consumes. Verify both cross-repo edges are inferred.

---

#### W0.4: Ownership from Code

Populate ownership without requiring humans to declare it:

- Parse `CODEOWNERS` files (GitHub, GitLab, Bitbucket formats).
- Extract `owner` from `package.json`, `Cargo.toml` (authors, maintainers).
- Fallback: `git log --format='%ae'` → most frequent author = owner.
- Store on `RepoBundle.contracts` and `owners` fields (already reserved, currently unused).

Ownership enables team-scoped views: `sruja human map --team @fintech`.

```
File: crates/sruja-scan/src/ownership.rs (new ~200 lines)
File: crates/sruja-cli/src/commands/federation.rs (wire into publish())
```

**Validation:** Run on a repo with CODEOWNERS → verify owners are correctly extracted and appear in `repo.bundle.json`.

---

### Phase 1: Three Commands Humans Actually Use (5 weeks)

**Goal:** Ship the three commands that answer the three questions engineers ask every day:

1. **"What happens when..."** → `sruja human trace`
2. **"What is this thing?"** → `sruja human explain`
3. **"How does the system work?"** → `sruja human map`

All three work from scan alone. DSL adds richness where available. No `.sruja` file required.

---

#### W1.1: `sruja human trace` — "What happens when..."

The flagship. Traces a flow across all repos in the system.

```bash
$ sruja human trace "user clicks checkout"

── Trace: "user clicks checkout" ──

[frontend]   WebApp → POST /api/checkout
[gateway]    APIGateway → routes to cart-service
[cart]       CartService → SQL READ CartDB
[payments]   PaymentService → gRPC FraudService
[payments]   PaymentService → REST StripeAdapter
[payments]   PaymentService → KAFKA PaymentEvents
[orders]     OrderService ← KAFKA PaymentEvents
[orders]     OrderService → SQL WRITE OrdersDB
[orders]     OrderService → KAFKA OrderCreated

5 repos · 4 teams · 2 topics · 2 databases

⚠ SPOF: FraudService (sync, no fallback)
⚠ SPOF: APIGateway (single entry point)

Decisions: ADR-012 (sync fraud), ADR-008 (Kafka events)
Owners: @checkout-ui @platform @commerce @fintech @risk
```

```bash
$ sruja human trace "user clicks checkout" --depth 5    # deeper
$ sruja human trace "user clicks checkout" --team @fintech  # my team's involvement
$ sruja human trace "user clicks checkout" --json        # machine-readable
```

**How it works:**
1. Resolve query to entry point(s) — cascade: exact match → keyword → local embedding similarity → LLM disambiguate (only if ambiguous). Steps 1-3 are free. Step 4 costs ~$0.001.
2. BFS traversal through `SystemGraph`, following `→` edges. Deterministic. Free.
3. At each hop: resolve repo, load technology/owner/criticality/gotchas. Free.
4. SPOF detection: nodes with high betweenness + single incoming path. Deterministic. Free.
5. Render as compact flow diagram. Template. Free. Keep under 50 lines.

**Cost: $0 by default. ~$0.001 only when entity resolution is ambiguous and requires LLM disambiguation.**

```
File: crates/sruja-cli/src/commands/trace.rs (new ~500 lines)
```

---

#### W1.2: `sruja human explain` — "What is this thing?"

Tells a human *why* something exists, not just what it does. The situation model builder.

```bash
$ sruja human explain PaymentService

── PaymentService ──
  repo: payments  |  team: @fintech  |  criticality: HIGH

What it does:
  Initiates payment transactions for the checkout flow.
  Calls FraudService synchronously for risk assessment.
  Processes charges via StripeAdapter.
  Publishes payment events to Kafka.

Where it fits:
  ← CartService (cart repo) sends checkout requests
  ← WebhookHandler (payments repo) receives Stripe callbacks
  → FraudService (fraud repo) for risk checks
  → StripeAdapter (payments repo) for charges
  → Kafka PaymentEvents → OrderService, 3 other consumers

What to know before changing it:
  ⚠ FraudService has no fallback — if it's down, payments fail
  ⚠ PaymentEvents is v2 schema — v1 consumers removed 2025-Q1
  ⚠ Stripe webhook handler is in a separate module
  🔒 Only CartService and WebhookHandler may call it directly
  🔒 Must NOT access OrdersDB directly

What it affects (blast radius):
  OrderService (orders repo) — HIGH risk
  PaymentEvents topic — 4 consumers across 3 repos
  FraudService (fraud repo) — contract change needed

Decisions: ADR-012 (sync fraud check), ADR-008 (Kafka for events)
```

```bash
$ sruja human explain PaymentService --md        # markdown output
$ sruja human explain PaymentService --persist   # save to docs/architecture/PaymentService.md
```

**How it works:**
1. Resolve element by name or ID — cascade: exact → keyword → local embedding. All free.
2. Load from `SystemGraph` (cross-repo topology) + local scan data. Free.
3. Sections: purpose, where it fits (cross-repo), gotchas, boundaries, blast radius, decisions. All deterministic from graph + template rendering. Free.
4. Gotchas and boundaries come from DSL intent layer if present, otherwise inferred (undocumented high-centrality nodes = implicit gotcha). Free.
5. Keep under 40 lines. Compass, not encyclopedia.
6. `--enrich` flag: send structured facts to LLM for prose polish. Costs ~$0.01-0.02. Optional.

**Cost: $0 by default. ~$0.02 with `--enrich`.**

```
File: crates/sruja-cli/src/commands/explain_cmd.rs (new ~450 lines)
```

---

#### W1.3: `sruja human map` — "How does the system work?"

A compressed cognitive map. The "new engineer onboarding" command.

```bash
$ sruja human map

── E-Commerce Platform ──
5 repos · 12 services · 4 databases · 3 topics · 4 teams

Frontend (frontend repo · @checkout-ui)
  └─ WebApp [React] → REST → APIGateway

APIGateway (infra repo · @platform)
  ├─→ CartService [Go]
  ├─→ PaymentService [Rust] ★ HIGH
  └─→ OrderService [Node.js]

CartService (cart repo · @checkout-ui)
  └─ CartDB [PostgreSQL]

PaymentService (payments repo · @fintech)
  ├─→ FraudService [Python] (fraud repo · @risk)
  ├─→ StripeAdapter [Rust]
  └─→ Kafka: PaymentEvents → 4 consumers

OrderService (orders repo · @commerce)
  ├─ OrdersDB [PostgreSQL]
  └─→ Kafka: OrderCreated → 2 consumers

★ SPOF: FraudService (sync, no fallback)
⚠ 2 undocumented services detected by scan
⚠ orders repo baseline drifted (3 new deps since last sync)
```

```bash
$ sruja human map --team @fintech       # only what my team owns/touches
$ sruja human map --focus PaymentService  # neighborhood around a service
$ sruja human map --drift                # highlight what's changed recently
$ sruja human map --html                 # interactive web view
```

**How it works:**
1. Load `SystemGraph`. Compute hierarchical layout by repo → service → dependency. Free.
2. Render as ASCII tree (default). Each node: name, technology, repo, team. Free.
3. Overlay: SPOF markers, criticality, drift status, undocumented services. Free.
4. Keep under 50 lines / ~1,000 tokens.
5. `--html` flag generates the existing HTML explorer but from SystemGraph. Free.
6. `--enrich` flag: LLM polishes the map into a narrative overview. ~$0.01. Optional.

**Cost: $0 by default. ~$0.01 with `--enrich`.**

```
File: crates/sruja-cli/src/commands/map.rs (new ~500 lines)
```

---

#### W1.4: Wire MCP for Cross-Repo

Extend MCP tools so AI editors can also traverse cross-repo:

- `sruja_get_topology`: accept element ID with `repo::` prefix, traverse across repos
- `sruja_find_path`: pathfind across repos
- `sruja_get_neighbors`: follow cross-repo edges
- New: `sruja_trace_flow` — MCP version of `sruja trace`
- New: `sruja_explain_element` — MCP version of `sruja explain`

```
File: crates/sruja-cli/src/commands/mcp/definitions.rs (extend, ~80 lines)
File: crates/sruja-cli/src/commands/mcp/run_tool/graph.rs (extend, ~150 lines)
```

---

**Phase 1 Validation:**

The real test: give 3 engineers who've never seen a codebase 30 minutes with `sruja trace`, `explain`, and `map`. Can they describe the system accurately? Can they identify the riskiest components? Can they explain why certain decisions were made?

If yes, the plan works. If no, the output format needs iteration, not more features.

---

### Phase 2: Make It Sticky (4 weeks)

**Goal:** Humans come back to Sruja daily, not just during onboarding. Make comprehension part of the development workflow.

---

#### W2.1: `sruja daily` — Morning Intelligence Briefing

Every morning, an engineer wants to know: what changed? What should I care about? **Entirely deterministic — runs in CI for free.**

```bash
$ sruja daily

── Daily Briefing · Mon Jun 1 ──

Changes in your repos (last 24h):
  payments: 4 commits by @jane — "add refund flow"
    → New dependency on Redis (not in previous scan)
    → PaymentService blast radius now includes refund path
  orders: 1 commit by @bob — "fix race condition"
  cart: no changes

⚠ Attention needed:
  PaymentService added Redis dependency. 
    4 repos depend on PaymentService. Run: sruja human explain PaymentService
  FraudService baseline drifted (2 undocumented changes).
    Run: sruja human explain FraudService

Your team's (@fintech) services:
  PaymentService — HIGH criticality · 4 downstream repos
  FraudService — MEDIUM criticality · 2 downstream repos
  StripeAdapter — LOW criticality · 1 downstream repo

✓ No boundary violations
✓ All tests passing (last CI run: 2h ago)
```

Extend the existing `sruja daily`/`sruja review` command with cross-repo awareness, cognitive debt signals, and team-scoped views.

**Cost: $0 — all deterministic (git diff + graph diff + template rendering).**

```
File: crates/sruja-cli/src/commands/review.rs (extend, ~300 lines)
```

---

#### W2.2: `sruja before` — Pre-Change Impact Check

Before touching code, check what you're about to affect. **Entirely deterministic — runs instantly, costs nothing.**

```bash
$ sruja human before src/payment.rs

── Impact Preview: src/payment.rs ──

You're about to change: PaymentService (payments repo)
Criticality: HIGH · 4 downstream repos · 8 consumers

Who it affects:
  OrderService (orders repo) — directly calls PaymentService
  FraudService (fraud repo) — PaymentService is its primary caller
  PaymentEvents Kafka — 4 consumers across 3 repos

What to know:
  ⚠ FraudService has no fallback — your change might break it
  🔒 Boundary rule: PaymentService must not access OrdersDB
  📋 ADR-012 applies (sync fraud check) — consider if your change affects this

Who to notify: @commerce (orders), @risk (fraud)

Run after your change:
  sruja human trace "user clicks checkout" — verify flow still works
  sruja drift — check for new violations
```

This is the human-centric version of `sruja focus`. Instead of briefing an AI, it briefs the human about what they're about to touch.

**Cost: $0 — blast radius from graph + template rendering.**

```
File: crates/sruja-cli/src/commands/before.rs (new ~400 lines)
```

---

#### W2.3: Web System Explorer

Extend the existing HTML explorer to support cross-repo system landscapes:

- System landscape view: repos as groups, services as nodes, cross-repo edges as connections.
- Click a service → see its `explain` page.
- Filter by team, repo, criticality, technology.
- Embed `trace` results as animated flow paths.
- One command: `sruja human map --html` → opens in browser.

```
File: crates/sruja-export/src/explorer.rs (extend, ~400 lines)
```

---

#### W2.4: VS Code Integration

Extend the VS Code extension with comprehension commands:

- **"Sruja: Trace Flow"** — input a description, see cross-repo flow in a webview.
- **"Sruja: Explain This"** — right-click a file/symbol, get the explain output.
- **"Sruja: What Am I Changing?"** — before saving, show impact preview.
- **System Map view** — sidebar tree showing the federated system landscape.

```
File: extension/src/commands/comprehension.ts (new ~350 lines)
File: extension/package.json (add commands and views)
```

---

### Phase 3: AI Amplification (5 weeks)

**Goal:** Use AI to proactively surface understanding gaps and generate polished narratives. But always grounded — the graph is truth, AI renders. And always cost-aware — deterministic is free, LLM is opt-in.

---

#### W3.1: Cognitive Debt Score

A single number that answers: "How well does this team understand their system?"

**Entirely deterministic. No LLM needed.** All metrics are computed from the graph + git data:

```bash
$ sruja cognitive-debt

── Cognitive Debt Report ──

HIGH RISK:
  PaymentService (payments repo)
    8 downstream consumers · 4 repos · 2 undocumented deps · 0 recent ADRs
    Bus factor: 1 (@jane authored 73% of changes)
    → If @jane leaves or PaymentService breaks, 4 teams are blocked.
    → Run: sruja human explain PaymentService

MEDIUM RISK:
  APIGateway (infra repo)
    Hub node (12 edges) · no gotchas documented · no runbook
    → Critical choke point with no operational knowledge captured.

LOW RISK:
  CartService (cart repo)
    2 consumers · well-documented · 3 ADRs · team of 4

System score: 62/100 (needs attention)
Threshold: 70 (your CI gate)
```

**Metrics per element:**
- **Undocumented blast radius**: downstream consumers not in any DSL/policy × criticality
- **ADR staleness**: months since last ADR affecting this element
- **Bus factor**: % of changes by single author
- **Hub without docs**: high betweenness × zero gotchas/runbooks
- **Cross-repo coupling**: number of repos depending on this element

```
File: crates/sruja-graph/src/debt.rs (new ~300 lines)
File: crates/sruja-cli/src/commands/cognitive_debt.rs (new ~350 lines)
```

**Cost: $0 — all graph metrics and git statistics.**

---

#### W3.2: Grounded Narratives (Cost-Optimized)

The `--enrich` flag exists. Make it work properly and cheaply:

**Two-tier approach:**
- **Default (free):** Template rendering from structured facts. Every `explain`, `trace`, `map` works perfectly without LLM. Templates are deterministic, fast, and produce structured human-readable output.
- **`--enrich` (paid):** Send structured facts to LLM for prose polish. Uses small model routing and prompt caching to minimize cost.

**Cost optimization for `--enrich`:**
1. **Prompt caching:** Send repo architecture as cached prefix (~2K tokens cached, ~60% cost reduction). Extend the existing `build_cache_friendly_task_export()` pattern.
2. **Small model routing:** Entity disambiguation and template → prose use Haiku/Flash (~$0.002/call). Only risk narratives use Sonnet (~$0.02/call). New `auto` routing mode in `.sruja/config.toml`.
3. **Strict grounding:** *"Only use the provided data. Do not infer, fabricate, or add information not present in the input."* Keeps output short (fewer output tokens = lower cost) and accurate.
4. **Token budget enforcement:** Max 1,000 output tokens per enrichment call. Enforced by the existing `TokenBudget` system.

**Key invariant: if the narrative contradicts the graph, the graph wins.**

```
File: crates/sruja-cli/src/narrative.rs (new ~250 lines)
File: crates/sruja-cli/src/enrichment.rs (extend, ~100 lines — caching + routing)
```

**Cost: $0 default. $0.002–0.02 with `--enrich` depending on task and model routing.**

---

#### W3.3: Semantic Entity Resolution (Local, Free)

Wire the existing `vector.rs` embedding module so `trace` and `explain` find things by description — **all local, no API call**:

- Index all nodes from scan graph (labels, descriptions, technologies) using fastembed BGE-small-en-v1.5 (already a dependency, runs via ONNX on CPU).
- `sruja human trace "how does payment work"` → matches PaymentService even if the user didn't use the exact name.
- `sruja human explain "the thing that calls stripe"` → resolves to StripeAdapter.
- Entity resolution cascade: exact match (free) → keyword (free) → embedding cosine top-3 (free, local) → LLM disambiguate ($0.001, only if 2+ candidates score within 5%).

**Cost: $0 for 95%+ of queries. ~$0.001 when truly ambiguous.**

```
File: crates/sruja-cli/src/commands/context/logic.rs (extend, ~100 lines)
File: crates/sruja-export/src/vector.rs (extend for scan graph, ~80 lines)
```

---

#### W3.4: `sruja human what-if` — Safe Change Modeling

Before making a change, simulate the impact:

**Two-tier output:**
- **Default (free):** Deterministic blast radius analysis. Graph mutation + template rendering. Shows direct effect, blast radius (repos/teams/topics/databases), and affected decisions. All from graph traversal.
- **`--enrich` (paid):** LLM adds risk reasoning — why something is HIGH risk, what the implications are. Uses Sonnet for nuanced reasoning (~$0.02).

```bash
$ sruja human what-if "remove FraudService sync check"

── What-If ──

Direct effect:
  PaymentService: removes sync call, -200ms latency
  FraudService: loses 87% of its traffic

Blast radius: 3 repos · 2 Kafka topics · 0 databases

Risks:
  HIGH — Fraud moves async, fraud rate may spike until manual review catches up
  MEDIUM — FraudService capacity needs re-planning (87% traffic drop)
  LOW — PaymentEvents schema might need fraud_status field

Decisions to update: ADR-012 (sync fraud check) → supersede

Next steps:
  1. Write ADR for async fraud before coding
  2. Run: sruja human explain FraudService
  3. Notify @fintech @risk
```

```
File: crates/sruja-cli/src/commands/what_if.rs (new ~450 lines)
```

**Cost: $0 default. ~$0.02 with `--enrich` (only when human wants risk narrative).**

---

### Phase 4: Organization-Scale (6 weeks)

**Goal:** Sruja works across the entire engineering org, not just a handful of repos.

---

#### W4.1: Continuous Federation

Auto-discovery for organizations with many repos:

- `.sruja/org.json` lists repos (or auto-discover from GitHub/GitLab org).
- CI hook: `sruja publish` runs on every merge to main.
- Incremental compose: only re-process changed bundles.
- System index stays current. Stale repos are flagged.

```
File: crates/sruja-cli/src/commands/org.rs (new ~400 lines)
```

---

#### W4.2: Knowledge Persistence

When senior engineers leave, their mental models shouldn't leave with them:

- `sruja human explain PaymentService --persist` → saves to `docs/architecture/PaymentService.md`.
- `sruja human map --persist` → saves the system map as a living document.
- When code changes, Sruja flags which persisted docs are now stale.
- Onboarding docs stay current without manual maintenance.

```
File: crates/sruja-cli/src/commands/explain_cmd.rs (extend, ~80 lines)
File: crates/sruja-cli/src/commands/map.rs (extend, ~80 lines)
```

---

#### W4.3: Cross-PR Comprehension

When reviewing PRs that span multiple repos:

```bash
$ sruja diff-pr payments/123 orders/456

Combined impact: 6 repos · 4 teams
Shared zone: PaymentEvents Kafka topic (schema change)

payments/123 "Add refund flow":
  → PaymentService: +3 methods, +1 Kafka consumer
  → publishes: RefundRequested event

orders/456 "Handle refund orders":
  → OrderService: +1 Kafka consumer for RefundRequested
  → Depends on: payments/123 (must merge first)

✓ No boundary violations
⚠ Merge order: payments/123 must land before orders/456
```

```
File: crates/sruja-cli/src/commands/diff.rs (extend, ~300 lines)
```

---

## Dependency Graph

```
Phase 0 — Scan-First Foundation (3 weeks)
  │
  ├─ W0.1 sruja init → scan-first (standalone)
  ├─ W0.2 SystemGraph traversal (standalone)
  ├─ W0.3 Cross-repo edge inference — local embeddings (standalone)
  └─ W0.4 Ownership from code (standalone)
       │
Phase 1 — Three Commands (5 weeks)
  │     depends on: W0.2, W0.3, W0.4
  │
  ├─ W1.1 sruja human trace ($0 default)
  ├─ W1.2 sruja human explain ($0 default, $0.02 with --enrich)
  ├─ W1.3 sruja human map ($0 default)
  └─ W1.4 MCP cross-repo wiring
       │
Phase 2 — Make It Sticky (4 weeks)
  │     depends on: Phase 1
  │
  ├─ W2.1 sruja human daily — morning briefing ($0)
  ├─ W2.2 sruja human before — pre-change impact ($0)
  ├─ W2.3 Web explorer ($0)
  └─ W2.4 VS Code integration
       │
Phase 3 — AI Amplification (5 weeks)
  │     depends on: Phase 1
  │
  ├─ W3.1 Cognitive debt score ($0)
  ├─ W3.2 Grounded narratives ($0.002–0.02 with --enrich only)
  ├─ W3.3 Semantic entity resolution ($0 local embeddings, $0.001 LLM fallback)
  ├─ W3.4 sruja human what-if ($0 default, $0.02 with --enrich)
  └─ W3.5 Cost dashboard + usage tracking
       │
Phase 4 — Organization-Scale (6 weeks)
         depends on: Phase 2 + Phase 3
  │
  ├─ W4.1 Continuous federation ($0 — all deterministic)
  ├─ W4.2 Knowledge persistence ($0)
  └─ W4.3 Cross-PR comprehension ($0)
```

---

## Timeline

| Phase | Weeks | When | Ships |
|---|---|---|---|
| 0 | 3 | Jul 2026 | Scan-first init + traversable SystemGraph |
| 1 | 5 | Jul–Aug 2026 | `trace`, `explain`, `map` — the three daily commands |
| 2 | 4 | Sep 2026 | `daily`, `before`, web explorer, VS Code |
| 3 | 5 | Oct–Nov 2026 | Cognitive debt, narratives, what-if |
| 4 | 6 | Dec 2026 – Jan 2027 | Org-scale federation, persistence, cross-PR |

**Phases 0–1 (8 weeks) = the v1 release.** Three commands that work from scan alone, across repos, answering the three questions engineers ask every day.

---

## What We're NOT Building

- **An autonomous coding agent.** Sruja helps humans understand, not write.
- **An IDE-only tool.** CLI-first. Terminal is universal.
- **A monitoring platform.** That's Datadog. Sruja works with static code.
- **A documentation generator.** Sruja generates comprehension, not docs. Docs are a side effect of `--persist`.
- **An AI chatbot.** Sruja is a deterministic engine. AI is optional enrichment.

---

## Success Metrics

| Signal | Target | How to measure |
|---|---|---|
| Onboarding time | 50% reduction | New engineers describe system after 2h with `map`+`trace` |
| Change confidence | Engineers can name blast radius before coding | `sruja before` usage |
| Cognitive debt visibility | All HIGH-risk elements surfaced in CI | `sruja human cognitive-debt --ci` exit code |
| Daily usage | >30% of engineers run a comprehension command daily | Opt-in telemetry |
| Review quality | Fewer "I didn't realize this would break X" incidents | Incident retrospectives |
| **LLM cost per engineer** | **< $2/month** | `sruja costs` — 95% of usage is free |
| **LLM cost for CI** | **$0** | No LLM calls in CI pipeline |

---

## Competitive Moat

| | Sourcegraph | CodeSee | Backstage | Structurizr | **Sruja** |
|---|---|---|---|---|---|
| Works from code alone | Search index | Partial | Manual entry | Manual entry | **Yes — scan-first** |
| Cross-repo traversal | No | Visual only | Catalog only | No | **Yes** |
| Architecture enforcement | No | No | No | No | **Yes** |
| Human comprehension (not search) | No | Maps only | Catalog only | Diagrams only | **trace, explain, map** |
| Decision rationale | No | No | No | Manual | **ADRs + why tracing** |
| Stays synced with code | Search index | Partial | Manual | No | **Yes — scan + drift** |
| Zero setup required | No | No | Heavy setup | No | **sruja init → value** |
| **Near-zero operating cost** | **Paid plans** | **Paid** | **Self-host infra** | **Paid** | **$0 default, < $2/mo per engineer** |

The moat is the combination: **zero-setup scan + cross-repo traversal + enforcement + human comprehension + near-zero cost** — from a single source of truth that auto-discovers from code and stays current.

---

## Risks

| Risk | Mitigation |
|---|---|
| Scan quality varies by language | Tree-sitter supports 13 languages; confidence scoring flags low-quality discoveries |
| Cross-repo edges might be wrong | Confidence levels on every inferred edge; low-confidence clearly marked |
| LLM hallucinates in narratives | Strict grounding — narrative is a rendering of facts, never a source. Fallback to templates. |
| LLM costs spiral | Every feature works without LLM. `--enrich` is opt-in. Prompt caching + small model routing. `sruja costs` makes spending visible. |
| Nobody uses comprehension tools | Lead with `sruja trace` — answers the #1 question: "what happens when..." |
| Terminal UI is niche | CLI is the universal interface. Web explorer and VS Code for those who prefer GUI. |
| Adoption friction | `sruja init` is zero-config. No DSL required. Value from second 1. No LLM key needed. |

---

## The One-Liner

**Sruja is the comprehension engine that lets any human understand any system — by auto-discovering architecture from code and answering human questions across repos, teams, and services. It costs nothing to run and uses AI only when you want richer output.**
