# How the Open Code Review Session Viewer Interface Works: Architecture, Security, and Data Flow

> Explore the alibaba/open-code-review Session Viewer interface. Understand its three-layer HTTP server architecture, host-guard security, and data flow for browsing and replaying code reviews.

- Repository: [Alibaba/open-code-review](https://github.com/alibaba/open-code-review)
- Tags: architecture
- Published: 2026-08-06

---

**The Session Viewer is a lightweight, browser-based UI in open-code-review that lets you browse, replay, and analyze past code review sessions through a three-layer HTTP server architecture with built-in host-guard security.**

The `alibaba/open-code-review` project ships with a built-in **Session Viewer** that transforms locally stored JSONL transcripts into an interactive web interface. This component allows developers to inspect LLM-generated review outputs, replay reasoning timelines, and filter results by severity—all without sending sensitive code to external services. Understanding how the session viewer interface works reveals a thoughtfully designed balance between usability and security.

## Three-Layer Architecture of the Session Viewer

The Session Viewer implementation in `internal/viewer/` follows a clear separation of concerns across three layers: HTTP server setup, request routing with data handling, and template-based presentation.

### HTTP Server Layer

The entry point is [`internal/viewer/server.go`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/server.go), where the **`StartServer`** function creates a hardened HTTP server:

```go
// Simplified view of server.go responsibilities
mux := http.NewServeMux()
// Static assets mounted at /static/
// Routes registered for /, /r/{repo}, /r/{repo}/{sessionID}
// Wrapped with host-allowlist guard and security-header middleware

```

The server:
- Resolves the **sessions directory** (`SessionsRoot`, typically `~/.ocr/sessions/`)
- Registers static asset handlers
- Applies **host-guard middleware** (from [`hostguard.go`](https://github.com/alibaba/open-code-review/blob/main/hostguard.go)) to prevent DNS-rebind attacks
- Injects **security headers** via [`securityHeaders.go`](https://github.com/alibaba/open-code-review/blob/main/securityHeaders.go) (`Content-Security-Policy`, `X-Content-Type-Options`, etc.)

### Routing and Handler Layer

[`internal/viewer/handler.go`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/handler.go) implements three core handlers:

| Route | Handler Function | Purpose |
|-------|------------------|---------|
| `/` | `handleRepos` | Lists all repositories with stored sessions |
| `/r/{repo}` | `handleSessions` | Lists sessions for a specific repository |
| `/r/{repo}/{sessionID}` | `handleSession` | Renders detailed view of a single session |

These handlers:
- Call into [`internal/viewer/store.go`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/store.go) to locate and read **JSONL transcript files**
- Unmarshal spans into Go structs (`Session`, `ReviewComment`, etc.)
- Compute aggregates: **severity counts**, **task cards**, **comments grouped by file**
- Pass structured data to HTML templates

### Presentation Layer

The UI renders through:
- **HTML templates** in `templates/*.html` (repo list, session list, session detail)
- **Static assets**: [`static/style.css`](https://github.com/alibaba/open-code-review/blob/main/static/style.css) for styling, [`static/session.js`](https://github.com/alibaba/open-code-review/blob/main/static/session.js) for client-side interactivity

Template parsing uses `parseTemplate` with a `template.FuncMap` providing helpers:
- `formatDuration` – humanizes time spans
- `severityCounts` – aggregates issue severity
- `groupCommentsByFile` – organizes review output by affected file

## Security Measures Protecting Session Data

The session viewer implements two critical defenses against local data exposure:

### Host-Guard Protection

In [`hostguard.go`](https://github.com/alibaba/open-code-review/blob/main/hostguard.go), requests are filtered by `Host` header against an allow-list derived from:
- The `OCR_VIEWER_ALLOWED_HOSTS` environment variable, **or**
- The server's bind address

This prevents **DNS-rebind attacks** that could trick a browser into exposing session transcripts to malicious websites.

### Security-Header Middleware

[`securityHeaders.go`](https://github.com/alibaba/open-code-review/blob/main/securityHeaders.go) injects hardening headers on every response:
- `Content-Security-Policy` – restricts resource loading
- `X-Content-Type-Options: nosniff` – prevents MIME-type sniffing
- Additional headers for clickjacking and XSS protection

## Data Flow: From Review to Browser

The complete lifecycle of session data:

1. **Generation**: When `ocr review` finishes, the CLI writes a **JSONL transcript** (one line per telemetry span) to `~/.ocr/sessions/<repo>/<sessionID>.jsonl`

2. **Loading**: The Viewer calls [`store.go`](https://github.com/alibaba/open-code-review/blob/main/store.go) utilities to:
   - Discover available repositories and sessions
   - Stream-read JSONL files
   - Decode into Go structs

3. **Aggregation**: Handlers compute derived data structures for the UI:
   - Hierarchical navigation (repos → sessions → timeline)
   - Task cards for plan, main, relocation, and memory-compression phases
   - Filterable comment lists with severity badges

4. **Rendering**: Templates receive pre-computed data and generate HTML with `Content-Type: text/html`

## Launching the Session Viewer

Start the interface from your terminal:

```bash
ocr viewer                    # Default: 127.0.0.1:8080

ocr viewer --addr :3000       # Custom port

# Or via environment variable:

OCR_VIEWER_ADDR=0.0.0.0:8080 ocr viewer

```

The CLI command lives in [`cmd/opencodereview/viewer_cmd.go`](https://github.com/alibaba/open-code-review/blob/main/cmd/opencodereview/viewer_cmd.go), which parses flags and delegates to `viewer.StartServer(addr)`.

Enable external access only when needed (the host-guard will still enforce allow-list validation):

```bash
OCR_VIEWER_ALLOWED_HOSTS="localhost,myhost.example.com" ocr viewer --addr 0.0.0.0:8080

```

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`cmd/opencodereview/viewer_cmd.go`](https://github.com/alibaba/open-code-review/blob/main/cmd/opencodereview/viewer_cmd.go) | CLI entry point, flag parsing |
| [`internal/viewer/server.go`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/server.go) | HTTP server setup, middleware wrapping |
| [`internal/viewer/handler.go`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/handler.go) | Request handlers for three route patterns |
| [`internal/viewer/store.go`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/store.go) | Session directory resolution, JSONL loading |
| [`internal/viewer/hostguard.go`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/hostguard.go) | Host-allowlist security filter |
| [`internal/viewer/securityHeaders.go`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/securityHeaders.go) | Response header hardening |
| `internal/viewer/templates/*.html` | Go HTML templates |
| [`internal/viewer/static/style.css`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/static/style.css) | UI styling |
| [`internal/viewer/static/session.js`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/static/session.js) | Timeline interactivity, filtering |

## Summary

- The **Session Viewer** provides browser-based access to locally stored review transcripts without external dependencies
- **Three-layer architecture** separates server setup ([`server.go`](https://github.com/alibaba/open-code-review/blob/main/server.go)), data handling ([`handler.go`](https://github.com/alibaba/open-code-review/blob/main/handler.go)), and presentation (templates/static assets)
- **Host-guard middleware** and **security headers** protect against DNS-rebind and injection attacks
- **JSONL transcripts** are read on-demand and aggregated into filterable, hierarchical views
- Launch with `ocr viewer`—bind address and allow-list configurable via flags or environment

## Frequently Asked Questions

### How do I access the Session Viewer from another machine?

Set `OCR_VIEWER_ADDR=0.0.0.0:8080` and add your hostname to `OCR_VIEWER_ALLOWED_HOSTS`. The host-guard will reject requests from unlisted Host headers even when bound to all interfaces.

### Where are session files stored?

Transcripts live in `~/.ocr/sessions/<repo>/<sessionID>.jsonl`. The [`store.go`](https://github.com/alibaba/open-code-review/blob/main/store.go) utilities resolve this path and stream-read the JSONL format—one JSON object per line representing telemetry spans.

### Can I customize the viewer's appearance?

The templates in `internal/viewer/templates/` and styles in [`internal/viewer/static/style.css`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/static/style.css) can be modified before rebuilding. The Go template system uses a `FuncMap` with helpers like `formatDuration` for consistent rendering.

### What data structures power the session detail page?

The `handleSession` function in [`handler.go`](https://github.com/alibaba/open-code-review/blob/main/handler.go) unmarshals spans into `Session` and `ReviewComment` structs, then computes aggregates: severity counts, task-phase cards, and file-grouped comments. These pre-computed structures drive the timeline and filtering UI.