# portal A content-driven question engine: one Rust binary that turns a Git repo of YAML into a live site — pages, forms, review desks and state machines, with a durable event-sourced record of every answer underneath. The engine special-cases nothing. Everything a site serves is declared in its content repo, content pushes hot-reload every running instance, and the same build serves any number of sites: instances differ only by environment variables. [uhhm.no](https://uhhm.no) and [redoal.com](https://redoal.com) are two faces of the same binary from the same release artifact. It composes with the surrounding stack rather than bundling it. Gitea hosts the content, NATS JetStream stores the events and projections, Kanidm provides identity, and anything downstream — automations, newsletters, onboarding — subscribes to the answer stream. ## Documentation Everything is under [`docs/`](docs/README.md): - [Architecture](docs/architecture.md) — what the engine is made of. - [Content reference](docs/content-reference.md) — every key a content repo may write. - [State machines](docs/state-machines.md) — `aggregates.yaml`. - [Access](docs/access.md) — the policy compiled from content. - [Operations](docs/operations.md) — releasing, deploying, adding a site. ## Development ```sh cargo leptos build # server + wasm cargo test --features ssr # tests/jetstream.rs needs PORTAL_TEST_NATS_URL ``` Content is linted by [iris](https://project.uhhm.no/uhhm/iris), which depends on this crate and carries the same version, so a content repo can check itself against the exact portal its instance runs: ```sh iris check --path questions ``` ## Releasing `cargo release patch` tags and pushes; CI builds the tarball and attaches it to the Gitea release. A site takes it by bumping `PORTAL_RELEASE` in its own content repo. See [operations](docs/operations.md).