Some things in SendOps — **Segments**, **Attributes**, **Lists**, and **Topics** today — can be authored in one of two ways. Every such definition has an **origin**, and the origin decides where you edit it:

- **Managed** — authored **in the SendOps app** (the in-dashboard editor, or the API). Managed definitions are fully editable in SendOps.
- **Git-backed** — authored as a **file in your connected repository**. Git-backed definitions are **read-only in the app** — the repository is the source of truth, and changes reach SendOps by a normal pull-request-and-merge, then a sync.

A definition is always exactly one of the two. There is **no two-way merge**: SendOps never writes back over a change you made in git, and a sync never overwrites a managed definition. This *exclusive ownership* is what keeps the two worlds from fighting over the same definition.


  Use **managed** authoring when you want to create and tweak segments quickly from the dashboard. Use **git-backed** authoring when you want your definitions reviewed, versioned, and deployed like the rest of your code — through pull requests. You can start managed and promote to git later, or adopt a git-backed segment back into the app. You don't have to choose up front.


## How you can tell them apart

On a Segment's page in the dashboard:

- A **managed** segment shows an **Edit** button and can be paused, re-evaluated, and deleted in the app.
- A **git-backed** segment shows a **Managed in git** badge and an **Edit in GitHub** link. Its definition is read-only in the app; you edit it in the repo.

Both kinds evaluate membership the same way — the origin only changes *where you author the rule*, not how it runs.

## Editing a managed segment

Open the segment and click **Edit**. You get a live editor with syntax highlighting, inline validation, autocomplete for your attributes, and a **Preview** that shows how many contacts currently match — all before you save. Saving snapshots a version (so you can restore a previous definition) and re-evaluates membership.

## Editing a git-backed segment

You **don't** edit it in the app — you edit the file in your repository and open a pull request. When the PR merges, the next sync brings your change into SendOps. The dashboard's **Edit in GitHub** link takes you straight to the file. See [Git-backed definitions](/templates/github-integration) for how the repository and manifest are wired up.

## Moving a segment between the two

The transitions are **explicit and one-shot** — never an automatic background sync in either direction.

### Promote: managed → git

**Promote** moves a managed segment into your repository so it can be reviewed and versioned as code.

1. Open a **managed** segment and click **Promote to git**.
2. SendOps opens a **pull request** that adds the segment's definition file and registers it in your `sendops.json` manifest.
3. The segment **stays managed and editable in the app** while the PR is open — you'll see a **Promotion to git pending** banner with a link to the PR.
4. When you **merge** the PR, the next sync **adopts** it: the segment becomes git-backed and read-only in the app.


  Promoting only opens a PR. If you don't merge it, the segment stays managed — so it's safe to promote, review, and decide later. Closing the PR without merging simply leaves the segment managed. And if you edit the segment in the app while its PR is still open, merging the now-out-of-date PR won't quietly overwrite your newer edit — SendOps keeps your change and asks you to re-promote to refresh the PR.


Promoting requires a connected GitHub repository with write access granted to the SendOps GitHub App. If the connection isn't configured for writes, promote will tell you.

### Adopt: git → managed

**Adopt** (a "defork") does the reverse: it takes a git-backed segment and makes it app-managed so you can edit it in the dashboard again.

1. Open a **git-backed** segment and click **Adopt into managed**.
2. The segment immediately becomes **managed and editable** in the app, and the sync no longer owns it.
3. **Remove the definition file from your repository** (and its `sendops.json` entry). If you leave it, each sync will report that it *skipped* the file because a managed segment now owns that key — harmless, but noisy.


  A segment's key is unique in your organization. You can't have a managed and a git-backed segment with the same key — the app refuses a managed key that a git file already owns, and the sync skips a git file whose key a managed segment already owns ("managed wins"). Promote and adopt respect this: a transition that would collide is blocked with a clear message.


## Attributes work the same way

Your **attribute schema** — the typed fields your segments reference as `attr.<name>` — follows the identical model. A managed attribute is edited in the dashboard's attribute editor; a git-backed one is declared in your repository's attribute-schema file (the file your `sendops.json` points at with its `"attributes"` key) and is read-only in the app. You **Promote** a managed attribute to git and **Adopt** a git-backed one back, exactly as with segments.

Two things are specific to attributes:

- **Every edit applies — it's never blocked.** Renaming or retyping an attribute can affect segments that reference it. SendOps doesn't stop you; instead the editor shows the **impact before you save** (which segments are affected, how many stored values stop matching), and a disruptive change asks you to confirm. Affected segments keep evaluating best-effort and carry an *evaluation-disrupted* warning until their rules are updated.
- **This holds no matter how the edit arrives.** An attribute change merged through git produces the same warnings as one made in the app — the merge isn't a back door around the impact checks.


  Attributes share a single schema file in your repo, so promoting one adds it to that file (creating the file and registering it in `sendops.json` the first time). Everything else — the pending-PR banner, "nothing changes until you merge", the safe-re-promote behaviour — matches segments.


## Lists and Topics work the same way

[Lists](/audience/lists) and [Topics](/audience/topics) follow the identical model, each with its own single manifest file — and, like attributes, each is registered in `sendops.json` as a **path string**, not an inline definition:

- The `lists` key of `sendops.json` is a path to a JSON file containing a map of `key` to `{ name?, description? }`.
- The `topics` key is a path to a JSON file containing a map of `name` to `{ display_name?, description?, default_subscription_status? }`.


  `attributes`, `lists`, and `topics` all work the same way in `sendops.json`: the manifest key is a **path to a single file**, and that file's contents are the map of definitions. `segments` and `workflows` are different — those manifest keys **are themselves** inline maps of `key → { path, name? }`, one entry per definition file. Mixing the two up (writing an inline map under `lists` or `topics`) is a common authoring mistake; SendOps rejects it with a "must be a file path string" validation error.


As with attributes, all of an org's git-backed Lists (or Topics) live together in that one file rather than one file per definition. **Promote** and **Adopt** work exactly as described above, and a git-backed List or Topic is read-only in the app until you adopt it back.

## Where this applies

**Segments, Attributes, Lists, and Topics** are the consumers of this managed-vs-git model today. **Email templates** already follow the same idea — authored as code in your repository and synced in — and [Drip Workflows](/workflows/overview#managed-vs-git-backed) are git-backed too, as `.flow` files declared under the manifest's `workflows` key. Over time still more definition types are expected to adopt the same convention, so the mental model you learn here carries across.