> ## Documentation Index
> Fetch the complete documentation index at: https://docs.emergence.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Register a New Solution

> End-to-end checklist for registering a new solution on the platform — name, namespace, image registry, Helm wiring, database, and platform integration.

# Register a New Solution

This is the canonical checklist for starting a new solution on CRAFT. Follow these steps when you're past the [Quickstart](/guides/solution-dev/quickstart) prototype and ready to make the solution real.

<Info>
  Most decisions here are conventions — the platform doesn't *force* you, but solutions that follow the conventions get free deployment, observability, and CI integration.
</Info>

## Registration sequence

```mermaid theme={null}
%%{init: {'theme': 'base', 'themeVariables': {'lineColor': '#555555', 'fontFamily': 'sans-serif', 'edgeLabelBackground': '#ffffff'}}}%%
flowchart LR
    NAME["1. Pick a name<br/>&lt;solution&gt;"]
    NS[("2. Create namespace<br/>em-&lt;solution&gt;")]
    REG["3. Choose image<br/>registry"]
    HELM["4. Wire Helm chart<br/>(em-service alias)"]
    DB[("5. Provision DB<br/>+ Alembic")]
    AG{"6. Has agents?"}
    AG_Y["Register via<br/>Assets API"]
    CONN{"7. Has data<br/>connections?"}
    CONN_Y["Register via<br/>Assets API"]
    INT["8. Wire integrations<br/>(auth/secrets/storage/LLMs)"]
    DONE([Solution live])

    NAME --> NS --> REG --> HELM --> DB --> AG
    AG -->|yes| AG_Y --> CONN
    AG -->|no| CONN
    CONN -->|yes| CONN_Y --> INT
    CONN -->|no| INT
    INT --> DONE

    classDef act fill:#E69F00,stroke:#555555,color:#000
    classDef store fill:#009E73,stroke:#555555,color:#000
    classDef q fill:#F0E442,stroke:#555555,color:#000
    classDef sol fill:#56B4E9,stroke:#555555,color:#000
    class NAME,REG,HELM,AG_Y,CONN_Y,INT act
    class NS,DB store
    class AG,CONN q
    class DONE sol
```

The dashed sequence is the **order**, not the schedule — most solutions land steps 1–4 in one PR, 5 in the next, and 6/7/8 incrementally. Steps 6 and 7 are conditional; only Tier 3 agentic solutions need them up front.

## Pre-flight checklist

<AccordionGroup>
  <Accordion title="Solution name picked (DNS-safe)">
    Lowercase, alphanumeric + hyphens only, ≤ 30 chars. Used as the Helm release name, the namespace suffix (`em-<name>`), and the package prefix in your monorepo.
  </Accordion>

  <Accordion title="Repository created">
    One repo per solution. Monorepo layout from day one — even with a single component — so adding a worker later is a 3-step diff. See [Architecture for Solution Developers](/guides/solution-dev/architecture-for-solution-developers#what-your-solution-owns).
  </Accordion>

  <Accordion title="Image registry chosen">
    Any OCI registry your target cluster can pull from. Internal solutions use `ghcr.io/emergenceai/`. Partners typically use their own registry.
  </Accordion>

  <Accordion title="Database design sketched">
    Your own Postgres database. No cross-service foreign keys. Migrations versioned with Alembic from day one.
  </Accordion>

  <Accordion title="Decided what gets registered with Assets">
    Agents, data connections, files, and models registered through the platform's Assets API are discoverable to other solutions and the UI. Decide upfront what your solution exposes.
  </Accordion>
</AccordionGroup>

## Steps

<Steps>
  <Step title="Pick a name">
    Match the solution name across:

    * Repo name (e.g. `em-talk2data`)
    * Helm release name (e.g. `talk2data`)
    * Namespace (e.g. `em-talk2data`)
    * Database (e.g. `talk2data`)

    Existing examples: `em-talk2data` (Data Insights), `em-data-readiness` (Data Governance), `em-semi` (Semiconductor). Stick to this rhythm — it makes ops searches and grep-based audits trivial.
  </Step>

  <Step title="Apply the namespace convention">
    | Namespace              | Used by                                                            |
    | ---------------------- | ------------------------------------------------------------------ |
    | `em-runtime`           | Platform services (Governance, Assets, Utils, Keycloak, OpenFGA)   |
    | `em-<solution>`        | Your solution's pods, services, and config                         |
    | `em-<solution>-system` | Cluster-scoped sidecars or operators owned by your solution (rare) |

    Create the namespace explicitly with a label so the platform's NetworkPolicy / Reloader / cost-attribution pick it up:

    ```bash theme={null}
    kubectl create namespace em-<solution>
    kubectl label namespace em-<solution> emergence.ai/solution=<solution>
    ```
  </Step>

  <Step title="Choose your container image registry">
    Configure `image.repository` in your chart's `values.yaml`. For private registries, also configure `imagePullSecrets`:

    ```yaml theme={null}
    api:
      image:
        repository: <your-registry>/<solution>-api
        tag: 0.1.0
      imagePullSecrets:
        - name: <your-pull-secret>
    ```
  </Step>

  <Step title="Wire the Helm chart">
    Single component? See [Quickstart Step 4](/guides/solution-dev/quickstart). Multi-component (api + worker + scheduler + agent…)? See [Package and Deploy](/guides/solution-dev/package-and-deploy) for the alias pattern.

    The minimum is one `em-service` subchart per component, with each component aliased so its values live under that key:

    ```yaml charts/<solution>/Chart.yaml theme={null}
    dependencies:
      - { name: em-service, alias: api,    version: 0.0.15, repository: oci://ghcr.io/emergenceai/em-charts }
      - { name: em-service, alias: worker, version: 0.0.15, repository: oci://ghcr.io/emergenceai/em-charts }
    ```
  </Step>

  <Step title="Register your database (your own, not platform's)">
    Your solution owns its database. Two non-negotiable rules:

    1. **No cross-service foreign keys.** Each service must be backup-restorable independently. Cross-service consistency is by API contract, not joins.
    2. **Migrations from day one** — Alembic is the platform standard. Migrations are immutable once committed; never edit a published migration, write a new one.

    Provision via your chart (the Postgres subchart pattern) or via Crossplane claims for managed databases. Connection string injected as a secret-backed env var (see [Manage Secrets](/guides/solution-dev/manage-secrets)).
  </Step>

  <Step title="Register agents (optional)">
    If your solution exposes A2A agents (the Data Insights pattern), register each with the Assets API so other services and the UI can discover them. Follow [Register Your First Agent](/guides/first-agent) — that walkthrough covers Agent Card authoring (`/.well-known/agent-card.json`), validation, registration, listing, and update with optimistic concurrency.
  </Step>

  <Step title="Register data connections (optional)">
    If your solution reads customer data (databases, object stores, file shares), the customer registers a [Data Connection](/platform/data-connections) and grants your solution permission. Your code fetches the connection at runtime — credentials never live in your config.
  </Step>

  <Step title="Wire integrations">
    Step through these in order:

    <CardGroup cols={2}>
      <Card title="Authenticate" icon="shield-check" href="/guides/solution-dev/authenticate-users">
        Validate JWTs and propagate `X-Project-ID`.
      </Card>

      <Card title="Secrets" icon="key" href="/guides/solution-dev/manage-secrets">
        Inject runtime secrets via the chart.
      </Card>

      <Card title="Storage" icon="database" href="/guides/solution-dev/use-shared-storage">
        Use obstore for cross-cloud blob access.
      </Card>

      <Card title="LLMs" icon="brain" href="/guides/solution-dev/access-llms">
        Call the LiteLLM gateway (never providers directly).
      </Card>
    </CardGroup>
  </Step>
</Steps>

## What you get when you follow the conventions

| If you…                                        | You get…                                                                                                   |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| Follow `em-<solution>` namespace               | Auto-applied NetworkPolicy, Reloader watching your Secrets, cost attribution by solution                   |
| Wrap `em-service` with one alias per component | Standard probes, env var deduplication, Gateway API ingress, HPA — all configurable but with sane defaults |
| Register agents in Assets                      | Discoverability from the UI shell + other solutions; permission integration with OpenFGA                   |
| Use Connections for data sources               | Credential rotation handled by the platform; never in your code                                            |
| Call LLMs via LiteLLM gateway                  | Per-project cost attribution, rate limits enforced centrally, traces in Langfuse                           |

## Verification

```bash theme={null}
# Namespace label set
kubectl get namespace em-<solution> -o jsonpath='{.metadata.labels}'

# Helm release lives in the right place
helm list -n em-<solution>

# Image pulls succeed (no ImagePullBackOff)
kubectl -n em-<solution> get pods

# DB migration ran (if applicable)
kubectl -n em-<solution> logs job/<solution>-migrate
```

If anything is unhealthy, see [Troubleshooting](/guides/solution-dev/troubleshooting).

## Next steps

<CardGroup cols={2}>
  <Card title="Package and deploy" icon="box" href="/guides/solution-dev/package-and-deploy">
    Multi-component charts, env overlays, image publish.
  </Card>

  <Card title="Local development" icon="laptop-code" href="/guides/solution-dev/local-development">
    Test changes locally before pushing.
  </Card>

  <Card title="Authenticate users" icon="shield-check" href="/guides/solution-dev/authenticate-users">
    The first integration most solutions need.
  </Card>

  <Card title="Troubleshooting" icon="circle-exclamation" href="/guides/solution-dev/troubleshooting">
    Common errors at registration time.
  </Card>
</CardGroup>
