# Analysis.md — Static Analysis of Whole Codebases via U

## What this is

A service that takes a codebase in PHP, JavaScript, TypeScript, or Python — a zip, a repo, a directory — transpiles every file to U with source maps, and runs analysis passes over the U representation. Errors, warnings, and capability reports reference the original source language, file, and line number. The developer never needs to read U.

The analysis happens on U, not on the original language. This is the key design choice. PHP, JS, and Python each have their own static analysis tools (PHPStan, ESLint, mypy), but none of them share a representation. A system that mixes PHP backend code with JS frontend code and Python ML code cannot be analyzed as a whole by any single tool. U is the common target. One codebase, one analysis, one capability graph.

## How it works

```
Source files (PHP, JS, TS, Python)
    ↓ transpilers (php-to-u.js, js-to-u-treesitter.js, py-to-u-treesitter.js)
U code + source maps
    ↓ U compiler analysis passes
Capability graph + errors + warnings
    ↓ source maps (V3/VLQ)
Reports referencing original source lines
```

Each transpiler returns `{code, messages, sourceMap}`. The source map entries are `{genLine, genCol, srcLine, srcCol, name}`, mapping every class, function, method, and property declaration in the U output back to the original file and line. When the analyzer flags something at U line 47, the report says `Db/Row.php:619` — the PHP line the developer wrote.

## What it can analyze

### 1. Capability tracking

Every U function declares what it can do through modifiers: `+IO` (filesystem), `+Net` (network), `+Crypto` (cryptographic operations), `+DB` (database access), `+Exec` (subprocess execution), `+Unsafe` (raw memory, FFI). The analyzer walks the call graph and verifies that every function only uses capabilities it declared or that its callers declared.

A function that calls `filesystem.write` without `+IO` in its signature chain is a violation. A module that imports `crypto.subtle` without `+Crypto` anywhere in its dependency tree is a violation. These are caught at analysis time, not at runtime.

Concrete example from the Qbix Platform Db classes (19 files, 15,057 lines PHP → 7,428 lines U):

| Module | Detected capabilities | Source evidence |
|--------|----------------------|-----------------|
| Db_Sqlite | +DB, +FS | Sqlite.php:52 `new Database(filePath)` |
| Db_Mysql | +DB, +Net | Mysql.php:99 `mysql2.createConnection(o)` |
| Db_Postgres | +DB, +Net | Postgres.php:47 `new pg.Client(connString)` |
| Db_Row | +Event | Row.php:619 `Q::event("Db/Row/$className/save")` |
| Db_Query | none (pure computation) | Query.php — builds SQL strings, no IO |
| Db_Expression | none (pure computation) | Expression.php — string concatenation only |
| Db_Utils | +FS, +Exec | Utils.php:829 heredoc templates written to files |

The analyzer produces this table automatically. A developer or auditor reads it and knows exactly what each module touches, with source links.

### 2. Data flow analysis

U's type system tracks where data comes from and where it goes. When a value flows from a user input (`Request.param`) through processing to a database query (`DB.query`), the analyzer can trace that path and flag missing sanitization.

| Finding | Source | Sink | Missing |
|---------|--------|------|---------|
| SQL injection risk | Request.php:45 `$_GET['id']` | Query.php:1595 `.where(criteria)` | No parameterized binding |
| XSS risk | Request.php:112 `$body` | Response.php:89 `.setSlot('content')` | No html_encode |
| Path traversal | Upload.php:33 `$filename` | Sqlite.php:52 `new Database(filePath)` | No path validation |

This works because U's transpilation normalizes all three languages into the same representation. A PHP `$_GET` and a JS `req.query` and a Python `request.args` all become the same U pattern: a read from an untrusted input source. The analyzer has one set of rules, not three.

### 3. Type safety across language boundaries

The Qbix Platform runs PHP on the server and JS in the browser, with the Db classes having parallel implementations in both languages. The analyzer can verify that the PHP and JS versions of the same class have compatible type signatures:

```
PHP: Db_Row::save(array $options): bool
JS:  Db.Row.prototype.save = function(options, callback)

Analysis: return type mismatch (PHP returns bool, JS uses callback)
          parameter type mismatch (PHP array, JS plain object)
          These are acceptable for async/sync split — no action needed.
```

This cross-language type checking is impossible with language-specific tools. ESLint doesn't know about PHP types. PHPStan doesn't know about JS callbacks. The U representation makes both visible.

### 4. Dependency and supply chain analysis

Every `require`, `include`, `import` in every language becomes a U `o` (import) statement. The analyzer builds the full dependency graph across languages:

```
Db.php
├── Db/Expression.php (pure)
├── Db/Query.php (pure)
│   ├── Db/Query/Mysql.php (+DB, +Net)
│   ├── Db/Query/Postgres.php (+DB, +Net)
│   └── Db/Query/Sqlite.php (+DB, +FS)
├── Db/Row.php (+Event)
│   └── Q.php (+Event, +Config)
├── Db/Result.php (pure)
└── Db/Utils.php (+FS, +Exec)
```

Each node shows its capabilities. If a dependency changes and gains a new capability (a library update adds network access), the analyzer flags it: "Db/Utils.php transitively gained +Net through updated dependency X at version Y."

### 5. Access control verification

The Qbix Platform uses access levels (`testReadLevel`, `testWriteLevel`, `testAdminLevel`) throughout its Streams system. The analyzer can verify that every data path checks access before returning data:

| Endpoint | Access check | Status |
|----------|-------------|--------|
| `Streams_stream_post` | `$stream->testWriteLevel('edit')` at line 34 | ✅ Checked before write |
| `Streams_stream_get` | `$stream->testReadLevel('content')` at line 22 | ✅ Checked before read |
| `Streams_message_post` | None found before `$stream->post()` | ⚠️ Missing access check |

This is static analysis of the access control pattern, not runtime enforcement. It catches the common bug where a developer adds a new endpoint and forgets the access check.

### 6. Dead code and unused dependency detection

The call graph built from the U representation shows which functions are actually reachable from the entry points (request handlers, CLI commands, event handlers). Functions that are never called, classes that are never instantiated, and imports that are never used show up as dead code:

```
Db/Utils.php: 12 of 47 functions unreachable from any entry point
  - compare_dbRows (line 28): only called by sort(), which is never called
  - generateModels (line 823): code generation utility, not used at runtime
  - ...
```

### 7. Concurrency analysis

U's fiber model (`+A` for async) makes concurrency explicit. The analyzer can detect potential race conditions where two fibers access the same mutable state (`+M`) without synchronization:

```
Warning: Row.php:205 $fieldsModified (mutable) accessed by:
  - save() fiber at Row.php:619
  - retrieve() fiber at Row.php:2189
  No synchronization between these access paths.
```

### 8. Performance analysis

The U representation makes algorithmic complexity visible. Nested loops, repeated allocations, and unnecessary copies are structural properties of the U code:

```
Db/Query.php:866 _criteria_expression:
  O(n²) nested iteration — for each criteria key, scans all parameters
  Suggestion: build parameter index for O(n) lookup
  
Db/Row.php:757 modifiedFields:
  Allocates new array on every call — could cache
```

## Use cases

### Code audit for security review

A company submits their codebase for a security audit. Instead of an auditor manually reading PHP files, the analyzer produces a capability report, data flow analysis, and access control verification. The auditor reviews the findings, each linked to original source lines, and focuses attention on the flagged paths.

Time savings: a 100-file PHP codebase that takes a human auditor two weeks to review can have its mechanical findings (capability inventory, data flow, access checks) produced in minutes. The auditor spends their time on the findings that require judgment, not on reading code.

### Continuous integration

The analyzer runs on every pull request. If a change adds a new capability (a module that didn't do network IO now imports `curl`), the CI build flags it. The reviewer sees "this PR adds +Net to `PaymentProcessor.php` — was this intentional?" with a link to the exact line.

### Regulatory compliance

Financial services, healthcare, and government systems need to demonstrate that their software meets specific security requirements. The capability report is a machine-generated, reproducible artifact that shows exactly what each module can do, grounded in the source code. An auditor can verify the report by re-running the analysis — it's deterministic.

### Supply chain security

When a dependency updates, the analyzer diffs the capability graphs before and after. If version 2.3.1 of a library had capabilities `[+DB, +Crypto]` and version 2.4.0 has `[+DB, +Crypto, +Net, +Exec]`, that's a supply chain risk flag. The new capabilities are traced to specific lines in the updated library.

### Multi-language refactoring

A team migrating from PHP to TypeScript needs to verify that the new code has the same behavior as the old code. Both versions transpile to U. The analyzer compares the U representations: same function signatures, same capability profiles, same data flow patterns. Discrepancies are reported with source lines in both languages.

### Safebox pre-deployment analysis

Before code runs inside a Safebox, the analysis verifies that its capability declarations match its actual behavior. A module that declares `[+DB]` but actually uses `[+DB, +Net]` is rejected. The M-of-N signers attest not just that the code was reviewed, but that the analysis passed and the capabilities are truthfully declared.

### Educational use

Students submit code. The analyzer shows them what their code actually does — not what they think it does. "Your function declares it only reads from the database, but it also writes to the filesystem at line 47 through this call chain: ..." This is a teaching tool for understanding side effects and separation of concerns.

## What exists today

| Component | Status | Lines |
|-----------|--------|-------|
| PHP→U transpiler (JS) | ✅ Production, source maps | 2,113 |
| JS→U transpiler (tree-sitter) | ✅ Production, source maps | 936 |
| Python→U transpiler (tree-sitter) | ✅ Production, source maps | 897 |
| JS→U transpiler (acorn, standalone) | ✅ Production, source maps | 155 |
| Source map module (V3/VLQ) | ✅ Shared, browser+Node | 132 |
| Zend engine bridge (PHP 8.3) | ✅ Tested, 24/24 | 443 |
| N-API bridge (Node v22) | ✅ Tested, 36/36 | 314 |
| Bidirectional event loop | ✅ Tested, 10/10 | 332 + 291 |
| Qbix Db transpilation | ✅ 19/19 files, 15K→7.4K lines | — |
| Qbix Db ORM execution (SQLite + MySQL + PostgreSQL) | ✅ 40/40 PHP, 24/24 JS | — |
| Bootstrap chain (JS→U→u2c→C→binary) | ✅ 3,080 JS → 1,997 U | — |

| Component | Status | What's needed |
|-----------|--------|--------------|
| Capability annotation system (`+IO`, `+Net`, `+FS`, `+Crypto`, `+DB`, `+Exec`) | 🔜 Not yet | Define in U spec, add to module signatures |
| Capability analysis pass in u2c | 🔜 Not yet | Walk call graph, check declarations vs usage |
| Data flow analysis pass | 🔜 Not yet | Track tainted inputs through function calls |
| Cross-language type comparison | 🔜 Not yet | Diff PHP and JS U representations |
| Access control pattern detection | 🔜 Not yet | Define patterns (testReadLevel, auth checks) |
| M-of-N signing in .u module format | 🔜 Not yet | Header with signature slots, verification |
| Site playground with source map display | 🔜 Not yet | Two-pane editor, click-to-navigate, annotations |
| Zip upload and batch analysis | 🔜 Not yet | Frontend + backend for multi-file projects |

## Architecture

The analyzer is a pipeline, not a monolith. Each pass is independent and composable:

```
                    ┌─────────────┐
                    │ Source files │
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │ Transpilers │  PHP→U, JS→U, Python→U
                    │ + source    │  (each returns {code, messages, sourceMap})
                    │   maps      │
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │  U modules  │  One .u file per source file
                    │  + .map     │  Source maps alongside
                    └──────┬──────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
       ┌──────▼──────┐ ┌──▼────┐ ┌────▼─────┐
       │ Capability  │ │ Data  │ │ Type     │
       │ analysis    │ │ flow  │ │ safety   │
       └──────┬──────┘ └──┬────┘ └────┬─────┘
              │            │            │
              └────────────┼────────────┘
                           │
                    ┌──────▼──────┐
                    │  Findings   │  Each references original source
                    │  + source   │  via source maps
                    │    links    │
                    └──────┬──────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
       ┌──────▼──────┐ ┌──▼────┐ ┌────▼─────┐
       │ CI report   │ │ Audit │ │ Safebox  │
       │             │ │ doc   │ │ signing  │
       └─────────────┘ └───────┘ └──────────┘
```

The pipeline is deterministic. Same input, same output. The analysis is reproducible by anyone with the same version of the transpilers and analysis passes. This is what makes it suitable for regulatory compliance and M-of-N attestation — the signers can independently verify the results.
