Repository Structure
Callora is the framework repository: a set of packable .NET 10 libraries plus first-party plugins and the documentation site. The runnable entrypoint and package composition live in the separate callora-production repository. The solution that ties everything together is Callora.Host.sln.
Top-level layout
src/ framework libraries (the platform)
custom/ first-party plugins + the plugin SDK
tests/ xUnit test projects (Core + analyzers) and test plugins
docfx/ this documentation site
docs/ local design notes, ADRs, runbooks (gitignored in part)
scripts/ dev helpers (dev-build.sh, dev-test.sh, dev-check.sh, build-repo-map.sh)
ops/ frontdoor config, Asterisk interop fixtures, runbooks
Callora.Host.sln the solution
Directory.Build.props / Directory.Packages.props shared build + Central Package Management
global.json pinned .NET 10 SDKNote: the admin and surface shells run colocated in the framework libraries — the Vue 3 admin shell in
src/Administration(served at/admin) and the server-side surface runtime insrc/Surface.Rendering(served at/surface-app). The former standalone Nuxt shells underapps/have been retired.
src/ — the framework libraries
| Project | Package / purpose |
|---|---|
src/Core | Callora.Core — domain-neutral platform core: Identity/RBAC, tenancy, plugin lifecycle, the event bus, persistence, the operator API host surface. This is the library the distribution publishes as the host backend. |
src/Administration | Callora.Administration — operator API plus the colocated Vue 3 admin shell (Resources/app/administration). Ships its built SPA as a static web asset served at /admin. |
src/Workspace | Callora.Workspace — the workspace (surface) API. To be renamed Callora.Surface. |
src/Surface.Rendering | Callora.Surface.Rendering — server-side surface template rendering (Nunjucks on a hardened Jint sandbox, ADR-015) plus the colocated Vue surface runtime (Resources/app/surface) served at /surface-app. |
src/Host/Cli | Callora.Host.Cli — the callora CLI (plugin contract-test kit, plugin sign). |
src/Analyzers | Callora.Analyzers — Roslyn governance analyzers (CAL0001 internal-consumption guard, CAL0003 contract-documentation, extension-point-id analyzer). Referenced as an analyzer by the framework projects. |
Each framework library carries PublicAPI.Shipped.txt / PublicAPI.Unshipped.txt for public-surface baseline tracking (any change to the public API shows up as a reviewable diff).
custom/ — plugins and the SDK
| Path | Purpose |
|---|---|
custom/static-plugins/Communication | System-tier VoIP/communication plugin (Callora.Plugin.Communication), bundled with the distribution. Ships its public contracts in src/Abstractions (Callora.Plugin.Communication.Abstractions). |
custom/static-plugins/Composer | System-tier surface editor (Callora.Plugin.Composer). |
custom/plugins/ | Empty by design — the install target for application-tier plugins, filled at runtime by the distribution or the operator API. |
src/Surface.Rendering/Resources/app/surface | @callora/surface — the surface runtime, and the package plugins compile against. Its src/public/ directory is the contract; there is no separate SDK package restating it. Apache-2.0. |
Plugins carry their own EF Core migrations and live in an isolated plugin_<id> PostgreSQL schema (e.g. plugin_communication). See Migration & Rollback.
tests/
| Project | Scope |
|---|---|
tests/Callora.Core.Tests | Host/core behaviour, plus architecture tests that enforce the structure rules (no nested/partial types, one type per file, DDD layering). |
tests/Callora.Analyzers.Tests | Roslyn analyzer verification. |
tests/TestPlugins/* | Plugin fixtures (e.g. Callora.TestPlugin.Exporting) used by the lifecycle tests. |
Fast tests run without external services (in-memory stores). Slow tests are tagged [Trait("Category","Slow")] and use Testcontainers PostgreSQL — see Build & Release.
docfx/
The conceptual documentation site (this guide included) is built with VitePress under docs-site/. The .NET API reference is generated separately by DocFX (docfx/docfx.json, from the XML docs of src/**/*.csproj and custom/plugins/**/*.csproj, excluding tests and bin/obj) and served at /api/.
Module boundaries and dependency direction
The dependency direction is strict and enforced by analyzers and architecture tests. It is the single most important structural invariant a maintainer protects.
Corenever references the modules.Administration,Workspace, andSurface.Renderingall referenceCore;Corereferences none of them. Identity/RBAC and tenancy stay inCore.- Within every project, the DDD layering from
CODE_STRUCTURE_RULES.mdholds:Domaindepends on nothing (no EF, no ASP.NET);Applicationdepends only onDomainand defines ports as interfaces;Infrastructureimplements those ports;Apistays thin and delegates toApplication. Wiring (port → adapter) happens only in the composition root. - The API top level splits
Workspace/(tenant-scoped) fromAdmin/(operator-scoped). - Plugins build against the contract, not against internals. Framework assemblies set
CalloraFrameworkAssembly=truein their.csprojand may consume the[CalloraInternal]surface. Any other compilation — every plugin — leaves itfalse, and the CAL0001 analyzer rejects consumption of the internal surface. The contract surface (public contracts,Extensibility,[CalloraExtensible]) is the defined extension boundary.
Where this is heading
The plugins under custom/static-plugins move into their own private repositories and come back as packages. Their contracts stay public, so a third party can build against ICommunicationChannelRegistry without seeing the implementation — the surface a marketplace needs. See ADR-020.
One rule keeps that possible, and it is enforced rather than documented: no project under src/ may reference a plugin implementation. A reference to a plugin's .Abstractions project is fine — the distribution has to load the contract into the default assembly load context for type identity to hold. The architecture test PlatformDependsOnPluginContractsOnlyTests fails the build the moment someone draws the other edge, rather than when an outsider's clone stops restoring.
scripts/golden-path.sh is the counterpart: it packs, installs the CLI as a dotnet tool, scaffolds a plugin, builds it against the packages, runs the contract test and signs it. That is the only run in this repository that crosses the package boundary — and every problem the boundary hides was found by crossing it, never by the test suite.
Status:
docs/REPO_MAP.mdis auto-generated and, at time of writing, still reflects an older layout (src/Host,src/Contracts,src/Abstractions). The live filesystem and this guide are authoritative; regenerate the map withscripts/build-repo-map.shwhen it drifts.