Packages

Phoenix-native AI ops: LLM traces, evals, prompt versions, replay, tool governance, and MCP workflows. Ecto-backed, LiveView-included.

Current section

Files

Jump to
scoria guides maintainers.md
Raw

guides/maintainers.md

# Maintainers
This guide is intentionally packaged for Scoria maintainers. It covers CI topology, release-preview proof, docs maintenance, release recovery, warning ratchet commands, installer contract proofs, and dev-only inspection surfaces. Adopter-first docs should start with [Getting Started](guides/getting-started.md), [Reviewer Verification](guides/reviewer-verification.md), and the [Glossary](guides/reference/glossary.md); do not move maintainer-only commands into README.
For the public ownership boundary behind maintainer verification, keep the README section [What Scoria owns vs what your app owns](README.md#what-scoria-owns-vs-what-your-app-owns) and [Ownership Boundary](guides/ownership-boundary.md) aligned.
## CI gate map
GitHub Actions runs parallel verify jobs:
```text
policy -> build -> { test, ratchet, knowledge, connector, full-suite[x4] } -> verify-summary
```
The `ci-gate` umbrella job in `.github/workflows/ci.yml` fails if the reusable verify workflow fails. Branch protection and release automation require `CI / ci-gate`. Executable jobs live in `.github/workflows/ci-verify.yml`; `.github/workflows/ci.yml` is the PR entrypoint. The `build` job declares `needs: policy`; the parallel verify jobs declare `needs: build` and fan into `verify-summary`.
Policy job:
1. `$ mix scoria.warning_baseline.check`
2. `$ mix scoria.warning_inventory.check_baseline`
3. `$ mix compile --warnings-as-errors`
4. `$ mix test --warnings-as-errors test/scoria/ci_policy_contract_test.exs test/scoria/verification_lanes_test.exs test/scoria/adoption_surface_test.exs`
Test job:
1. `MIX_ENV=dev mix scoria.release_preview`
2. `$ mix ecto.create` and `$ mix ecto.migrate`
3. `$ mix test.adoption`
4. `$ mix test.runtime_to_handoff`
5. `$ mix test.semantic_fast_path --warnings-as-errors`
Parallel verify jobs:
| Job | Local command |
|-----|---------------|
| `ratchet` | `SCORIA_DB_PORT=55432 MIX_ENV=test mix test --warnings-as-errors test/scoria/warning_inventory/tmp_preflight_test.exs` |
| `knowledge` | `SCORIA_DB_PORT=55432 mix test.knowledge --warnings-as-errors` |
| `connector` | `SCORIA_DB_PORT=55432 mix test.connector --warnings-as-errors` |
| `full-suite (k/4)` | `SCORIA_DB_PORT=55432 MIX_TEST_PARTITION=k mix test --warnings-as-errors --partitions 4` |
**Local parity.** Use `SCORIA_DB_PORT=55432` for local parity. CI binds Postgres below the Linux ephemeral range; local dev/test retains 55432.
**Ratchet is maintainer-only.** The `ratchet` lane runs `$ mix scoria.warning_ratchet.test` and never blocks adopter closeout; only maintainers move the accepted warning baseline.
When CI fails, run the matching maintainer command next: each parallel job above maps to exactly one local command, so reproduce the red job's command locally before pushing again instead of re-running CI to guess.
**Version namespaces**
Release proofs are versioned by milestone. Historical proofs live under their own namespaces — for example the archived `v2.x` adoption and connector proofs recorded in `.planning/milestones/` — while the active release train targets the current `0.1.x` Hex line.
**PR vs release proof depth**
Two proof depths guard the release train. PR CI proves the working tree; the release and publish chain proves the actual published tarball against the live registry.
| Depth | Runs on | What it proves |
|-------|---------|----------------|
| PR proof | every PR and `main` | `$ mix test.adoption` runs the adoption suite against in-repo source, including a `content-revision upgrade` check on the seeded prompt registry. |
| Tarball consumer full overlay | `publish-hex` job and `post-publish-smoke.yml` | `$ mix scoria.post_publish_smoke` unpacks the published Hex tarball into `scoria-0.1.0-unpack`, overlays it on a throwaway consumer app, and runs a semver upgrade proof. |
The overlay compares three tarballs: the `HEAD tarball` built from the release SHA, the `baseline exact previous` release pulled from Hex, and the `target just-published` version. A green overlay means the exact bytes published to Hex install and upgrade cleanly — not merely that the working tree does.
## Release preview and docs maintenance
Run release preview before publish-facing docs, package, or ExDoc changes merge:
```bash
mix scoria.release_preview
```
This command builds docs with warnings-as-errors and checks an unpacked local Hex preview for required runtime files, migrations, README, canonical guides, compatibility stubs, and docs brand assets. In CI, run the same verification suite as:
```bash
MIX_ENV=dev mix scoria.release_preview
```
ExDoc is a dev-only dependency, so `MIX_ENV=dev` is the CI environment for release preview. Do not present `MIX_ENV=test mix scoria.release_preview` as the supported contract.
For direct docs inspection:
```bash
MIX_ENV=dev mix docs --warnings-as-errors
```
Use the direct docs command as a diagnostic shortcut when release preview reports an ExDoc warning. Release preview remains the canonical package and docs proof. Rendered docs live in `doc/`, which is gitignored. Inspect `doc/index.html`, grouped guide extras, grouped public modules, logo/favicon rendering, redirects, and generated Markdown output when changing ExDoc configuration.
Keep this packaging boundary:
- Canonical public docs live under `guides/`.
- Old `docs/*.md` paths are compatibility stubs where copied links may exist.
- Dev-only docs such as design-system, Docker dev DX, UAT automation, component lab, screenshot harness, and generated browser artifacts stay out of adopter HexDocs unless a plan explicitly packages them.
- `guides/maintainers.md`, `CHANGELOG.md`, and `LICENSE` belong in the Maintainers ExDoc group.
## Local merge gate
`$ mix ci` reproduces the merge gate locally and exits non-zero on any failure.
It runs deps-lock checks, formatting, compile warnings-as-errors, pgvector preflight, and all gating verification suites from `Scoria.VerificationSuites`, plus optional knowledge, semantic cache, and connector proof unless `--skip-optional` is used.
```bash
mix ci
```
`$ mix ci --skip-optional` is partial proof only. It prints skipped lanes and exits non-zero so it cannot be mistaken for a clean merge gate.
## Installer contract proofs
Deep installer planner behavior is maintainer-only:
```bash
mix scoria.test.install_contract
```
Adopters use the no-write installer modes documented in [Reviewer Verification](guides/reviewer-verification.md):
```bash
mix scoria.install --dry-run
mix scoria.install --check
```
`--check` never writes host files. The final trailer is:
```text
SCORIA_CHECK_RESULT status=<compliant|drift|manual_review|error> exit_code=<0|1|2>
```
Use installer contract proof when changing planner classification, manifest behavior, no-write modes, or generated file mutation logic.
## Hex release & recovery {: #hex-release--recovery-maintainers}
**Normal patch release (fully automated).** Once `main` is green the release train needs no manual merge: Release Please opens the Release PR on a `release-please--branches--main` branch, release-branch CI runs, Release PR Auto-Merge merges it, and Release Please tags and publishes to Hex.
Two GitHub Actions secrets drive this automation:
- `RELEASE_PLEASE_TOKEN` — a fine-grained token that lets Release Please open and update the Release PR and dispatch the follow-up CI and Release Please runs.
- `HEX_API_KEY` — the Hex publish key consumed by the `publish-hex` job and by `hex-publish.yml` recovery.
Routine patch release flow:
1. Merge maintainer PRs to `main` using conventional commit prefixes.
2. Confirm `CI / ci-gate` is green on `main`.
3. Let Release Please open or update the patch Release PR.
4. Let release-branch CI pass.
5. Let Release PR Auto-Merge merge the Release PR and dispatch follow-up CI/Release Please.
6. Let Release Please tag and publish to Hex after tag SHA `ci-gate` succeeds.
7. Let post-publish registry attest run `$ mix scoria.post_publish_smoke`.
8. Verify `$ mix hex.info scoria` lists the new version.
Manual Hex publish recovery is only for cases where Release Please or Hex publish did not complete:
```bash
gh workflow run hex-publish.yml \
--ref v0.1.3 \
-f tag=v0.1.3 \
-f release_version=0.1.3
```
Do not republish a version already listed on Hex.
## Warning baseline and inventory
Maintainers enforce accepted warning debt expiry and classified inventory outside adopter closeout proof:
```bash
mix scoria.warning_baseline.check
MIX_ENV=test mix scoria.warning_inventory --write --scope full
MIX_ENV=test mix scoria.warning_ratchet.check
MIX_ENV=test mix scoria.warning_ratchet.test --warnings-as-errors
```
The ratchet capture is compile-only and maintainer-focused. Behavioral verification suites remain:
- `$ mix test.adoption`
- `$ mix test.runtime_to_handoff`
- `$ mix test.semantic_fast_path`
- `$ mix test.knowledge`
- `$ mix test.connector`
## Phase 44 dashboard scope proof
Review Queue, Eval Workbench, Prompt Registry, and Workflow Index now mount through DashboardScope. Tenant-owned evidence on those screens is loaded from the host-asserted dashboard scope; prompt templates and eval specs remain catalog metadata only where the Phase 44 summaries document that boundary.
Do not use a tenant query string to drive screenshot or maintainer proof scope. The dashboard harness must mount through host session data or a host resolver, and a tenant query hint must not change the asserted scope. Empty-state captures for tenant-owned evidence require either a freshly migrated database before seed or a host scope whose tenant has no rows.
Focused proof:
```bash
MIX_ENV=test mix test test/scoria_web/router_test.exs test/scoria_web/dashboard_scope_test.exs test/scoria_web/dashboard_scope_source_guard_test.exs test/scoria/adoption_surface_test.exs test/scoria_web/live/dashboard_auth_home_connectors_incidents_test.exs test/scoria_web/live/dashboard_auth_approvals_test.exs test/scoria_web/live/dashboard_auth_workflows_test.exs test/scoria_web/live/dashboard_auth_quality_data_test.exs test/scoria_web/live/dashboard_auth_prompts_test.exs --warnings-as-errors
```
## Design-system component conventions
For the maintainer conventions doc pairing every named design-system convention with its enforcing drift guard, see `docs/design_system.md` (dev-only; not shipped to Hex, so it is not part of this generated doc set and is referenced by path only, not as a doc link).
CSS selectors should stay component-oriented: prefer block classes, BEM modifiers, and inherited token variables over long structural selectors. A modifier-to-element selector is acceptable when that relationship is the component contract (`.scoria-table-shell--has-summary .scoria-table__viewport`), but avoid reaching through unrelated components such as panel -> table -> filter controls. For shared surface variants, add a `ScoriaWeb.UI` option such as `flush={true}` and let the component emit the modifier class.
Tables use one canonical compact scan density. Do not add user-facing compact/default/comfortable toggles; they add decision overhead without changing the operator job. If a table needs a different rhythm, solve it as a distinct component or documented surface variant instead of page-local row-density state.
## Dev-only inspection surfaces
The Component Lab, design-system guide, Docker dev DX guide, UAT automation docs, screenshot harness, and contact-sheet generator are maintainer development tools. They are useful for local inspection but should not become adopter HexDocs surface area without an explicit plan.
Component Lab proof:
```bash
mix test test/scoria_web/dev_lab_boundary_test.exs
make dev
mix scoria.ui.e2e --base-url http://localhost:4799/scoria
```
Screenshot pass:
```bash
make dev
mix run priv/repo/dev_seed.exs
mix scoria.ui.shots --url http://localhost:4799/scoria
```
Optional critique pass requires a process-scoped provider key:
```bash
op run --env-file "${SCORIA_OP_ENV_FILE:-.env.op}" -- mix scoria.ui.shots --critique --url http://localhost:4799/scoria
```
Do not store plaintext provider keys in `.env`, `.envrc`, shell history, logs, screenshots, or planning artifacts.