---
title: "How a run works"
description: "Follow the steps the Action takes from loading the config to making one commit."
canonical_url: "https://diglot.sh/workflow/action/how-a-run-works"
---
# How a run works

> Follow the steps the Action takes from loading the config to making one commit.

Understanding the order of a run explains why some segments are translated, some are updated and some are left alone. A run has five phases.

## 1. Load and fetch

The Action loads `diglot.config.ts` and `sources.yml`. For each source that has a `repo` and a `ref`, and whose `path` doesn't exist (by default `.diglot/checkouts/<repo>`), it fetches the ref shallowly into a bare repository. Existing working copies are read as they are.

## 2. Extract and diff

It writes a snapshot of the policy to `.diglot/policy.json`, then extracts the segments of each source at its ref and diffs them file by file against `.diglot/manifest/<source>.json`. Modified segments are paired with their predecessor, and the pairing is added to `.diglot/lineage.json` so that a later run can still find it. The new manifests are written. See [keeping in sync](https://diglot.sh/guide/concepts/keeping-in-sync) for the pairing rules.

## 3. Decide per segment

For each locale whose `locale.yml` enables machine translation, the Action handles every live segment that has no record. Identical text across sources and branches counts once. It takes one of these paths:

- If the segment has a predecessor whose record isn't rejected, it calls `updateTranslation` from [`@diglot/mt`](https://diglot.sh/machine-translation/update-translation). When the skeletons are identical and only the hash changed, the old text is carried over without a model call (`derived: carry`). Otherwise the model updates the text from the word difference (`derived: update`), including edits that only change case or punctuation. Updates run four at a time.
- Otherwise it calls [`translateSegments`](https://diglot.sh/machine-translation/translate-segments), which sends one request per page together with the locale's glossary and style.

Segments that are placeholder-only are skipped. A segment that was rejected by QA in an earlier run is skipped too, until its source changes or `retry-rejected` is set. If you set `limit`, updates are taken first, then new translations, up to the limit.

## 4. Write records

Every new record has `review: none`, and carries `prev` when there is a predecessor. A translated or updated record has `origin: mt`. A carried record keeps the predecessor's `origin` and `mt`. Carried and updated records read as `pending-review` until a person edits or verifies them. Then the Action updates the manifests and, unless `build-dist` is `false`, builds `dist/<locale>.json` for every locale from the live records.

Records that a reviewer rejected stay as they are and ship in the bundles, so their segments aren't translated again until their source changes.

## 5. Commit

The changed records, locale directories and state go into one commit under the given identity. The message summarises the run, for example:

```text
chore(fr): translate 78 segments, update 12, carry 31
```

With several locales, the body lists each locale, the rejections and the source revisions. When nothing was translated, the subject is `chore: sync <sources>`. The Action never commits the checkouts. Bundles are added with `--force` so they enter the commit even when git ignores them.

## Next steps

- [Inputs and outputs](https://diglot.sh/workflow/action/inputs-and-outputs) lists the options that change these decisions.
- [Rejected and skipped segments](https://diglot.sh/workflow/action/rejected-and-skipped) explains the segments a run leaves alone.


## Sitemap

See the full [sitemap](https://diglot.sh/sitemap.md) for all pages.
