EKOS — Enterprise Knowledge Operating System

Architecture document generation.
Alpha — real decomposition, real diagrams, real evidence.

Generated Architecture.md for a real, 2,000+ file Elixir/Phoenix + React codebase and it read as unprofessional: flat bullet lists, no backend, frontend, or database decomposition, and the one real diagram an unreadable single row of boxes. Six increments later, the same command produces real per-language AST decomposition, a real System Decomposition view, readable diagrams, and real cross-tier edges — all live-verified against the same real project, nothing mocked. This is the Alpha: shipped and working, honest about what's still deferred.

flat lists, unreadable diagram 6 increments, live-verified each time RFC 0081-0086 real Backend/Frontend/Database decomposition
§ 01 / the real problem
what "ekos docs generate --layout curated" produced, before

No source decomposition. No links. A diagram that couldn't be read.

EKOS's only two real AST-based decomposition analyzers were for Rust and Python. Elixir — 100% of this project's backend — and JS/TS — its entire frontend — got nothing but a crude declaration-prefix scan: bare symbol name strings, no relationships, no module hierarchy, no KIR objects at all. The one real diagram that did exist (System Context, RFC 0073) had a real, separately-tracked bug: a wide layer rendered as one unreadably long row rather than wrapping.

before — real gap, not exaggerated
## Components
- File: 1847
- Person: 124
- Table: 15          // flat counts, no
                        // backend/frontend split
                        // at all

## System Context
  [46 boxes, one row, 8296px wide]
§ 02 / real backend decomposition
RFC 0081 — new ekos-plugin-elixir + ElixirAnalyzerPass

1231 real Elixir files → 1355 real modules, 4810 real functions.

ekos recover — real, unedited
INFO elixir-analyzer complete pass=elixir-analyzer:analytics
     files=1231 modules=1355 symbols=4810

No mature Elixir-grammar Rust crate exists — a real, bounded, hand-written structural scanner instead. defmodule → real Custom("ElixirModule") objects; def/defp → real Custom("ElixirSymbol") objects, tagged public/private from the real keyword, not guessed; alias/import/use/require → real internal module-to-module DependsOn edges — the actual "restore links and relationships" deliverable. Spot-checked two known real files directly against the compiled ledger: exact function lists, exact dependency edges, matching the real source read directly.

§ 03 / real frontend decomposition
RFC 0082 (package.json) + RFC 0085 (oxc_parser) — a real bug found and fixed live

291 real JS/TS files, 78 real npm packages — and a real JSX-in-.js parser bug, caught before shipping.

78
real Technology objects from 4 real package.json manifests
444
real JsModule objects (real import specifiers)
862
real JsSymbol objects (functions, classes, components)

Picked oxc_parser over swc_ecma_parser after a real live comparison of both crates' license, API shape, and maturity — not a coin flip. First live run against the real project found 18 of 291 real files failing to parse: every one a real .js file containing real JSX (lazy-loader.js's own <div ref={ref}>), which a bare-extension guess doesn't enable JSX for. Fixed by forcing JSX on for JavaScript, deliberately left off for .ts (real generic-assertion ambiguity) — parse success went from 93.8% to 99.3%, re-verified against the same real files, not assumed fixed.

§ 04 / the actual deliverable
RFC 0083 — new "## System Decomposition" section, right after System Context

Backend, Frontend, Database — one real diagram, real counts, real edges.

system-decomposition.svg — real, unedited, this project
Backend (1232 files) Frontend (324 files) ClickHouse Database (config only, no tables compiled) SQL Database (57 tables)

Convention-based classification (.ex/.rs/.py → Backend, .js/.ts/.css → Frontend, real Table/source_system data → Database), with a real ekos.toml override escape hatch for when the convention gets a project's layout wrong — never a silent misclassification with no way out. This is the direct answer to "which components does it have and how do they relate," the most directly requested deliverable of the whole effort — this is the literal SVG file the pipeline writes to disk, embedded here unmodified.

§ 05 / the diagrams themselves, fixed
RFC 0084 — row-wrapping, a new Crate Topology SVG, an honest Component View

8296×190px, one unreadable row → 1488×470px, readable.

BeforeAfter
46-node layer, one row, 8296px widewraps at 8 nodes/row, 1488×470px
no standalone Crate Topology diagramnew crate-topology.svg — 44 real crates, reusing the same SVG renderer unmodified
crate w/ no matching rollup: silently vanished"2 crate(s) have no matching subsystem rollup ... ekos-benchmark, ekos-integration-tests"

The topological DAG layering itself was already correct — the bug was treating "one DAG layer" and "one visual row" as always the same thing. A purely visual wrap fixed it, verified live against EKOS's own self-dogfooded architecture docs (the real Rust workspace needed to actually exercise a 46-node layer).

§ 06 / real cross-tier edges
RFC 0086 — the plan's own "stretch" phase, shipped

A real Ecto adapter declaration becomes a real Backend → Database arrow.

lib/plausible/clickhouse_repo.ex — real source
use Ecto.Repo,
  otp_app: :plausible,
  adapter: Ecto.Adapters.ClickHouse,
  read_only: true

No new pass — extended elixir_analyzer.rs to read a real, in-source signal already there. Found a real duplication bug before shipping: this project declares 5 separate ClickHouse-adapter Repo modules, which would have each re-pushed a duplicate "ClickHouse" object without extending the existing cross-file dedup — fixed before it ever reached the ledger. Verified via ekl: all 6 real ClickHouse-adapter modules and all 3 real Postgres-adapter modules resolve to one real object per database, no duplicates.

§ 07 / found while building this very deck
devlog_90 — two real bugs, found by reading real output, not by testing

1,236 unrelated real modules, falsely merged at confidence 1.00.

a real generated page, before this fix — real, unedited
## Plausible.Auth.Password (ElixirModule)

### SameAs
- ← PlausibleWeb.Plugins.API.Schemas.Funnel.CreateRequest
  — confidence=1.00  // a password-hashing module and an
                             // API schema, "the same real thing"?

Picking this exact real module as a deck example surfaced it: `ElixirModule`/ `ElixirSymbol`/`JsModule`/`JsSymbol` (RFC 0081/0085) were never added to the identity resolver's own documented exclusion list — the identical failure six other object kinds had already hit and been fixed for. Direct CKM inspection found the real scale: one canonical module had 1,236 real false `SameAs` edges. Chasing why a first fix attempt didn't change anything surfaced a second, bigger bug: docs-generated/ was never excluded from this project's own `[observe] paths` — every build was re-ingesting EKOS's own past output as real source, feeding old errors back into the pipeline. Fixed both; a full clean rebuild dropped the ledger from 127,676 contaminated objects to 8,787 real ones, and this exact module's page to its real 3 relationships, nothing else.

§ 08 / the honest scorecard
Alpha means shipped and real — not means finished

What's real now. What's deliberately still open.

Real, shippedDeliberately deferred
Elixir backend: modules, functions, real depsPhoenix role tagging (controller/LiveView/context) — designed, cut over a real dedup-ordering risk
JS/TS frontend: modules, symbols, 99.3% parse rateRelative import resolution (./Dashboard → its real file)
Real Backend/Frontend/Database decomposition viewPer-table precision on cross-tier edges (adapter-level today, not per-table)
Readable diagrams, real Crate Topology SVGFrontend → Backend edges — explicitly lower-confidence, never attempted
Real Backend → Database edges (Ecto adapters)2/291 real TS files still fail under the pinned oxc_parser 0.133.0
Identity resolver exclusion list, self-referential docs ingestion — both fixedResidual fuzzy `SameAs` candidates (Document/Technology/Pipeline) — RFC 0060's own already-tracked territory

Nothing in the right column is a bug hidden from this deck — every one is named, scoped, and reasoned about in its own RFC or devlog. That's the actual meaning of "Alpha" here: real, live-verified, evidence-backed work, with a real, honest map of what comes next.

Try it yourself — nothing hidden, before or after

Same repo. Same command. Real output.

terminal
$ git clone https://github.com/plausible/analytics
$ cd analytics && ekos init
$ ekos build && ekos recover && ekos resolve && ekos compile && ekos commit
$ ekos docs generate --layout curated
$ open docs-generated/Architecture.md
Full workspace gateResult
cargo build/test/clippy -D warnings/fmt --checkClean, every increment
New tests this effort60+ new tests across 6 RFCs, each built from real fixtures or a real bug found live
EKOS · Architecture Document Generation, Alpha — RFC 0081-0086, devlogs 84-90 · every example on this page is real output, unedited · github.com/alexeyban/EKOS