# CX contributor front door — architecture

> **GENERATED FILE.** Source: `docs-src/llm/contributor-architecture.md.tmpl`,
> `registry/repos.cxd` and `deps.cxd`, assembled by
> `scripts/gen_docs/primer_build.cx`. The two tables are projections; the
> prose is the rules, each citing its decision. Edit the template or the
> registry, never this file.

- Two rings, frozen: **Ring 0** the data format (`cx-core-data`), **Ring 1**
  the language and its standard library (`cx-core-code`). Everything else is a
  **group** — platform, binding, ecosystem, dist — importing the rings plus
  what its row declares, acyclic (RULED: RS-1).
- One repository per product; `cx` is the front door that pins every one by
  sha and builds the binaries from the pins (RULED: RS-2, RS-3, RS-7).
- The core names no product: products register their builtins and CLI verbs
  from their own `init()` (RULED: D71a, D73a).
- Where a thing lives is DATA: `registry/repos.cxd` allots every tracked path
  to one repository; `registry/modules.cxd` declares every surface's ring and
  group. Read the row, not a directory listing.

## 1. Rings and groups — what each import contract buys

| Layer | What it may import | What that buys | Decision |
|---|---|---|---|
| Ring 0 — data | nothing above itself | a document cannot execute: parsing a file is always safe | RULED: RS-1 |
| Ring 1 — code | Ring 0 | a program cannot reach a socket, a store or a protocol without a platform module | RULED: RS-1 |
| platform group (`ring=1 group=platform`) | the rings + the products its row pins | state that outlives the program: store, net, mail, identity, fabric, xsp, xap | RULED: RS-1, RS-24 |
| binding / ecosystem / dist groups | the C ABI and the released binary | other languages, editors, the registry, the site | RULED: RS-1, RS-3 |

A module lives in the ring of its **highest verb**: pure or purely local is
Ring 1; serving, or reaching a store or a protocol, is the platform group
(RULED: OL-14). The daemons (`store-serve`, `fabric-serve`, `flow serve`, the
XAP host) stay subcommands of one `cx` (RULED: RS-10).

## 2. The repository map

`status=extracted` means the repository exists, owns its paths, and none of
them is tracked in the front door any more; a blank status is a row that still
allots paths here. `pins` is the import graph a V product may use (the
`product-import-gate` holds it); `V module` names the one `vcx/<m>/` directory
the product compiles from (RULED: RS-24).

<sub>Generated by `scripts/gen_docs/contributor_facts.cx` from `registry/repos.cxd`'s `[repo]` rows; `at=` (the pinned sha) and `why=` stay in the file (32 rows) — do not edit here: change the source, run `make docs`.</sub>

| repository | group | ring | ships | V module (`vcx/<m>/`) | pins | status | what it is |
|---|---|---|---|---|---|---|---|
| `cx` | dist | none | binary | — | — | — | the front door: pins every repo, builds the four cx builds and libcx-core/libcx, holds the site, the release, the installer |
| `cx-private` | dist | none | none | — | — | — | the private orchestration repository: boards, evidence, runner configuration, briefs |
| `cx-core-data` | core | 0 | binary | — | — | extracted | the data format: reader, writer, canonical form, schema, codecs, libcx-core, the data-only cx |
| `cx-core-code` | core | 1 | binary | — | `cx-core-data` | extracted | the language: evaluator, stdlib, LSP, libcx, the cli and embed builds |
| `cx-platform-net` | platform | none | binary | `cxnet` | `cx-core-code` | extracted | sockets, TLS, the HTTP server, the XSP transport bindings, ftp, sftp, file_surface |
| `cx-platform-mail` | platform | none | binary | `mail` | `cx-platform-net` | extracted | SMTP and IMAP, server and client cores |
| `cx-platform-identity` | platform | none | binary | `identity` | `cx-platform-store` `cx-platform-net` `cx-platform-xsp` | extracted | sessions, did:web, authz-store, vc-revocation |
| `cx-platform-store` | platform | none | binary | `store` | `cx-core-code` `cx-platform-net` `cx-platform-xsp` | extracted | the storage engine, its substrates, journal/live/audit, and the store server |
| `cx-platform-db` | platform | none | binary | `cxdb` | `cx-core-code` | extracted | external database access: $sql-*, $redis-*, the drivers |
| `cx-platform-fabric` | platform | none | binary | `fabric` | `cx-platform-store` `cx-platform-identity` `cx-platform-net` `cx-platform-xsp` | extracted | messaging and fabric-serve |
| `cx-platform-xsp` | platform | none | binary | `xsp` | `cx-core-code` | extracted | the XAP Stream Protocol: the XSP-AUTH handshake, the protocol pages |
| `cx-platform-xap` | platform | none | binary | `xap` | `cx-platform-net` `cx-platform-mail` `cx-platform-identity` `cx-platform-store` `cx-platform-db` `cx-platform-fabric` `cx-platform-xsp` | extracted | the application host, compose, dist, schema, market, the reference deployments |
| `cx-platform-flow` | platform | none | package | — | `cx-core-code` `cx-platform-store` | extracted | workflow; its CLI verbs stay in the binary |
| `cx-platform-connector` | platform | none | package | — | `cx-core-code` `cx-platform-mail` `cx-platform-store` | extracted | the connector kit and sync |
| `cx-platform-secrets` | platform | none | package | — | `cx-core-code` `cx-platform-connector` `cx-platform-store` | extracted | the minimal keystore: one handle grammar, one internal resolve seam, the PEP and the audit record, custody that rises by a provider row |
| `cx-platform-sso` | platform | none | package | — | `cx-core-code` `cx-platform-identity` `cx-platform-net` `cx-platform-store` | extracted | enterprise sign-on and its interop step |
| `cx-platform-ux` | platform | none | package | — | `cx-core-code` `cx-platform-flow` | extracted | the web and terminal surfaces |
| `cx-platform-workbench` | platform | none | package | — | `cx-core-code` | created | the document workbench — open, browse, comment on and safely modify a CX document |
| `cx-platform-agent` | platform | none | package | — | `cx-core-code` `cx-platform-store` `cx-platform-xap` | extracted | tools, mcp, mcp-server, a2a, a2a-xap, llm, run, adjudicate |
| `cx-binding-python` | binding | none | pypi | — | — | extracted | cxlib for Python |
| `cx-binding-go` | binding | none | go-module | — | — | extracted | cxlib for Go |
| `cx-binding-rust` | binding | none | crate | — | — | extracted | cxlib for Rust |
| `cx-binding-v` | binding | none | v-module | — | — | extracted | the native reference binding |
| `cx-binding-typescript` | binding | none | archived | — | — | — | archived at the ABI it was frozen with; lang/_archived/README.md names the version |
| `cx-binding-java` | binding | none | archived | — | — | — | archived at the ABI it was frozen with; lang/_archived/README.md names the version |
| `cx-binding-kotlin` | binding | none | archived | — | — | — | archived at the ABI it was frozen with; lang/_archived/README.md names the version |
| `cx-binding-csharp` | binding | none | archived | — | — | — | archived at the ABI it was frozen with; lang/_archived/README.md names the version |
| `cx-binding-swift` | binding | none | archived | — | — | — | archived at the ABI it was frozen with; lang/_archived/README.md names the version |
| `cx-binding-ruby` | binding | none | archived | — | — | — | archived at the ABI it was frozen with; lang/_archived/README.md names the version |
| `cx-registry` | ecosystem | none | none | — | — | extracted | the package index: the store, publisher keys, the publish program |
| `cx-decisions` | ecosystem | none | none | — | — | extracted | the ledger, the process specs, the standing rules, design texts |
| `cx-tooling` | ecosystem | none | editor | — | — | extracted | vscode, neovim, tree-sitter, completions, syntax, the installer |

## 3. The pins — how the front door is assembled

<sub>Generated by `scripts/gen_docs/contributor_facts.cx` from `deps.cxd`'s `[dep]` rows; each row's `sha` and `v-fork` sha stay in the file (24 rows) — do not edit here: change the source, run `make docs`.</sub>

| pinned repository | modules | V repository (carries `v-fork`) | the modules the pin provides |
|---|---|---|---|
| `cx-platform-agent` | 8 | no | `cx-platform/tools` `cx-platform/mcp` `cx-platform/mcp-server` `cx-platform/a2a` `cx-platform/a2a-xap` `cx-platform/llm` `cx-platform/run` `cx-platform/adjudicate` |
| `cx-platform-ux` | 3 | no | `cx-platform/ux` `cx-platform/ux-web` `cx-platform/ux-tui` |
| `cx-platform-workbench` | 1 | no | `cx-platform/workbench` |
| `cx-platform-sso` | 1 | no | `cx-platform/sso` |
| `cx-platform-flow` | 1 | no | `cx-platform/flow` |
| `cx-core-data` | 1 | yes | `cx-core-data` |
| `cx-core-code` | 57 | yes | `cx-stdlib/array` `cx-stdlib/authz` `cx-stdlib/bus` `cx-stdlib/bytes` `cx-stdlib/crypto` `cx-stdlib/csv` `cx-stdlib/cx` `cx-stdlib/diagram` `cx-stdlib/did` `cx-stdlib/email` `cx-stdlib/env` `cx-stdlib/format` `cx-stdlib/fp` `cx-stdlib/ft` `cx-stdlib/geo` `cx-stdlib/graphql` `cx-stdlib/hash` `cx-stdlib/html` `cx-stdlib/http-client` `cx-stdlib/i18n` `cx-stdlib/io` `cx-stdlib/json` `cx-stdlib/jsonrpc` `cx-stdlib/jsonschema` `cx-stdlib/locale` `cx-stdlib/log` `cx-stdlib/map` `cx-stdlib/math` `cx-stdlib/mime` `cx-stdlib/oidc` `cx-stdlib/path` `cx-stdlib/process` `cx-stdlib/prof` `cx-stdlib/random` `cx-stdlib/re` `cx-stdlib/saml` `cx-stdlib/sasl` `cx-stdlib/sched` `cx-stdlib/scim` `cx-stdlib/set` `cx-stdlib/similar` `cx-stdlib/soap` `cx-stdlib/strings` `cx-stdlib/supervise` `cx-stdlib/tar` `cx-stdlib/term` `cx-stdlib/test` `cx-stdlib/time` `cx-stdlib/url` `cx-stdlib/uuid` `cx-stdlib/validate` `cx-stdlib/vc` `cx-stdlib/ws` `cx-stdlib/xml` `cx-stdlib/xsp` `cx-stdlib/zip` `term` |
| `cx-platform-db` | 3 | yes | `db` `sql` `redis` |
| `cx-platform-net` | 4 | yes | `cx-platform/net` `cx-platform/http` `cx-platform/ftp` `cx-platform/sftp` |
| `cx-platform-mail` | 2 | yes | `cx-platform/imap` `cx-platform/smtp` |
| `cx-platform-store` | 4 | yes | `cx-platform/store` `cx-platform/journal` `cx-platform/live` `cx-platform/audit` |
| `cx-platform-identity` | 4 | yes | `cx-platform/session` `cx-platform/authz-store` `cx-platform/did-web` `cx-platform/vc-revocation` |
| `cx-platform-connector` | 2 | no | `cx-platform/connector` `cx-platform/sync` |
| `cx-platform-secrets` | 1 | no | `cx-platform/secrets` |
| `cx-platform-fabric` | 1 | yes | `cx-platform/fabric` |
| `cx-platform-xsp` | 1 | yes | `cx-platform/xsp-auth` |
| `cx-tooling` | 1 | no | `cx-tooling` |
| `cx-platform-xap` | 1 | yes | `cx-platform/xap` |
| `cx-registry` | 1 | no | `cx-registry` |
| `cx-decisions` | 1 | no | `cx-decisions` |
| `cx-binding-python` | 1 | no | `cx-binding-python` |
| `cx-binding-go` | 1 | no | `cx-binding-go` |
| `cx-binding-rust` | 1 | no | `cx-binding-rust` |
| `cx-binding-v` | 1 | no | `cx-binding-v` |

- `deps.cxd` is the ONE place a pin lives: one `[dep]` row per repository,
  its sha, the modules it provides, and the V-fork sha for a V repository
  (RULED: RS-7; the format is `spec/03-approved/process/repository-dependency-pins.md`).
- `cx deps sync` — the binary's verb, which `make deps-sync` calls — fetches each
  pin shallowly into the ignored `deps/<repo>/` and **fails** on a stale pin or
  a drifted checkout — it never warns; `cx deps sync --check` fetches nothing and
  refuses a checkout that is not at its pin. The program is
  `scripts/deps_sync.cx`, embedded in the binary (RULED: DEPSV-1).
- The build compiles every V module from its pinned checkout through `-path`:
  `make build-vcx` runs the Ring-1 repository's own `vcx/` build
  (`deps/cx-core-code/vcx`) with the front door's `deps.cxd` and `deps/` root,
  so the binary is exactly the pinned set.
- `cx` is a migration path, never a gate: a repository that releases is tried
  against the newest set that passes together; a pass advances its pin, a
  fail leaves it and files a finding on the repository that moved (RULED: RS-7, RS-8).

## 4. The registration hooks — the core names no product

| Hook | Where | A product does | Decision |
|---|---|---|---|
| builtin dispatch | `vcx/code/stdlib_builtin_registry.v` (`register_stdlib_builtin(family, f)`) | registers its `<family>_stdlib_builtin` from its own `init()`; a family registered twice panics naming both | RULED: D71a, RS-18 |
| CLI verb table | `vcx/code/cli_verb_registry.v` (`register_cli_verb(v)`) | registers its verbs (`store-serve`, …) from its own `init()` | RULED: D73a |
| the platform packs | `vcx/code/ring_registry.v` | registers its pack's dispatch entries from a `*_register.v` file of its own (`stdlib_session_register.v`, `sql_register.v`, …) | RULED: RS-18 |

What the hooks buy: a binary built WITHOUT a product answers that product's
names with the by-name refusal `CXER0136 E_NO_CALLABLE`, never a crash and never
another family's answer — which is what the profile gate probes.

## 5. Two-repository modules — the ring decides, not the consumer

A module whose pure V half is Ring 1 keeps that half in `cx-core-code` even
when its only consumer is one product; its CX surface, spec and corpus live
with the product (RULED: D76c, D84a, D78a):

| Module | V half (Ring 1, `cx-core-code`) | CX surface, spec, corpus |
|---|---|---|
| `sasl` | `vcx/code/stdlib_sasl.v` | `cx-platform-mail` |
| `ft` | `vcx/code/stdlib_ft.v` (the tokenizer `similar` calls) | `cx-platform-store` |
| `diagram` | the V diagram half | `cx-tooling` |

## 6. Documentation follows the module

Each repository generates its own reference fragment from its own corpus at
release; `cx`'s build embeds the docs of exactly the module versions it
compiles, and the one site in `cx` indexes every published fragment
(`docs/llm/manifest-fragment.cxd` per repository; RULED: RS-9, RS-28). The
component repositories stay thin: a README, CONTRIBUTING, the generated
fragment (RULED: D58a).

## 7. The public front door and the private working tree

The public `cx` is filtered from the private orchestration repository's passing
heads by the extraction recipe: every `repo=cx` path except the orchestration
set (runner evidence, per-tool scaffolding, the agent entry points), with the
ledger and the process specs public because `cx`'s own gate reads them
(RULED: D59a, D82a, D83a). A path's destination is its first-matching
`[path]` rule in `registry/repos.cxd`; `repos-allocation-gate` refuses a
tracked file no rule claims and a rule that claims nothing.
