diff --git a/docs/custom-repository-operations.md b/docs/custom-repository-operations.md
index dd3794a814..5e433a8c40 100644
--- a/docs/custom-repository-operations.md
+++ b/docs/custom-repository-operations.md
@@ -36,6 +36,10 @@ organization grants that token read-only cross-repository access to
## Translation workflow
+The complete Weblate architecture, translator procedure, promotion process,
+deployment instructions, troubleshooting, and recovery checklist are in
+[`dominican-translation-infrastructure.md`](dominican-translation-infrastructure.md).
+
The Tryton server owns `es_DO` as a standalone language; its database record
does not declare `es_419` (or any other locale) as parent. Complete Dominican
translations live beside each package in its regular `locale/es_DO.po`
diff --git a/docs/dominican-translation-infrastructure.md b/docs/dominican-translation-infrastructure.md
new file mode 100644
index 0000000000..da26b41c74
--- /dev/null
+++ b/docs/dominican-translation-infrastructure.md
@@ -0,0 +1,222 @@
+# Dominican Spanish translation infrastructure
+
+This document describes the production workflow for maintaining Spanish for
+the Dominican Republic (`es_DO`) in the customized Tryton repository. It is
+both an operating manual and a recovery reference.
+
+## Design goals
+
+- `es_DO` is a standalone Tryton language. It does not inherit from `es_419`.
+- Every maintained series has its own catalogs and translation branch.
+- Weblate never writes directly to a release branch.
+- Translation changes are reviewed and validated before promotion.
+- No password, personal access token, or API key is stored in Git.
+
+## Components and ownership
+
+| System | Responsibility |
+| --- | --- |
+| Official Tryton repository | Upstream source of Tryton changes. |
+| `tryton-do/tryton-mirror` | Read-only private mirror of upstream history. |
+| `tryton-do/tryton` | Customized source, Dominican catalogs, CI, and documentation. |
+| Gitea Actions | Validates catalogs, Python code, packages, and relevant tests. |
+| Weblate | Browser translation editor, checks, glossary, and translation memory. |
+| Gitea webhook | Tells Weblate that the source repository changed. |
+
+The data flow is:
+
+```text
+official upstream
+ |
+ v
+tryton-mirror ---- scheduled proposal ----> integration/8.0 ---- review ----> 8.0
+ ^
+ |
+Weblate <---- webhook ---- tryton repository |
+ | |
+ +---- translation/weblate-8.0 ---- PR ------+
+```
+
+The same isolated Weblate branch model is used for all maintained series. The
+8.0 production series adds the two-stage `integration/8.0` promotion gate.
+
+## Version mapping
+
+| Tryton series | Weblate project | Weblate Git branch | Promotion target |
+| --- | --- | --- | --- |
+| 6.0 | `tryton-6-0-es-do` | `translation/weblate-6.0` | `6.0` |
+| 7.0 | `tryton-7-0-es-do` | `translation/weblate-7.0` | `7.0` |
+| 8.0 | `tryton-8-0-es-do` | `translation/weblate-8.0` | `integration/8.0`, then `8.0` |
+| 8.2 | `tryton-8-2-es-do` | `translation/weblate-8.2` | `8.2` |
+
+Project pages are available below:
+
+-
+-
+-
+-
+
+Each project contains independent components for the server core, server
+resources, SAO, and every Tryton module present in that series. Component
+discovery on the server-core component detects module catalogs matching:
+
+```text
+modules//locale/es_DO.po
+```
+
+The manually managed catalogs are:
+
+```text
+trytond/trytond/ir/locale/es_DO.po
+trytond/trytond/res/locale/es_DO.po
+sao/locale/es_DO.po
+```
+
+Only `es_DO` is exposed by the component language filter. Weblate can reuse
+good translations between versions through shared translation memory, but it
+commits each version to its own branch and catalog.
+
+## Translator workflow
+
+1. Sign in to Weblate and open the project for the required Tryton series.
+2. Select Spanish (Dominican Republic) and the relevant component.
+3. Translate or improve a string. Preserve placeholders, XML/HTML markup,
+ keyboard accelerators, and plural forms exactly as Weblate indicates.
+4. Prefer Dominican accounting, tax, commercial, and administrative terms.
+ Use the project glossary for terminology that must be consistent.
+5. Resolve Weblate checks before marking work complete. Do not suppress a
+ failing check merely to increase the completion percentage.
+6. Use suggestions when the translator is uncertain; a reviewer can accept or
+ replace them without losing the discussion.
+
+Weblate groups pending edits and commits them after the configured delay. It
+then pushes to `translation/weblate-X.Y`. A translation is not released merely
+because it appears in Weblate; it must pass the Git review flow below.
+
+## Maintainer promotion workflow
+
+1. Confirm that the Weblate component has no repository error or lock.
+2. In Weblate, commit pending changes and push the repository when an immediate
+ release is required. Otherwise allow the automatic commit interval to run.
+3. Inspect the version's `translation/weblate-X.Y` branch in Gitea.
+4. Open a pull request to the promotion target from the version mapping table.
+5. Review terminology and confirm that the diff only contains expected PO
+ catalogs. Reject unrelated generated or source changes.
+6. Require the PO validation and relevant package tests to pass.
+7. Merge the pull request. For 8.0, open and review the second pull request from
+ `integration/8.0` to `8.0`.
+8. Allow the Gitea push webhook to refresh Weblate. If necessary, run
+ **Manage > Repository maintenance > Update** for the affected component.
+
+Never rebase or force-push a protected release or integration branch. If a
+Weblate branch must be repaired, first commit or discard pending Weblate work,
+then fast-forward the branch from its promotion target.
+
+## Deploying catalog changes
+
+Build or install the Tryton packages from the reviewed release branch. On each
+database, activate Spanish (Dominican Republic) as a translatable language and
+run:
+
+```console
+trytond-admin -d DATABASE --all --activate-dependencies
+```
+
+Restart the Tryton services after updating the installed package or container.
+Users can then select Spanish (Dominican Republic) in their preferences.
+`es_419` does not need to be active and is not a runtime dependency.
+
+For container deployments, update the image tag or immutable digest only after
+the new package build succeeds. Back up the database before a production
+module update and keep the previous image available for rollback.
+
+## Adding a Tryton series
+
+1. Create the release branch and `translation/weblate-X.Y` branch from the
+ same reviewed commit.
+2. Add `es_DO` to the core language data and add an `es_DO.po` catalog beside
+ every maintained core, resource, module, and SAO catalog.
+3. Create a Weblate project with hooks and shared translation memory enabled.
+4. Add the server-core and server-resources PO components.
+5. Add the SAO PO component.
+6. Add component discovery to server core with this regular expression:
+
+ ```text
+ ^modules/(?P[^/]+)/locale/(?Pes_DO)\.po$
+ ```
+
+7. Restrict languages to `^es_DO$`, disable creation of arbitrary languages,
+ enable push-on-commit, and point push to the dedicated translation branch.
+8. Verify that the component count equals modules plus core, resources, SAO,
+ and the automatically created glossary.
+9. Add CI and branch protection before accepting the first translation PR.
+
+## Webhook and credential model
+
+The Gitea repository has one active push webhook targeting:
+
+```text
+https://translate.tryton.org.do/hooks/gitea/
+```
+
+One repository-level webhook covers all translation branches. Weblate uses its
+own repository credential to fetch and push; Gitea Actions uses the short-lived
+repository-scoped `GITEA_TOKEN`. Personal passwords and Weblate API tokens must
+remain in the respective secret stores, never in workflow YAML, URLs, logs, or
+documentation.
+
+Rotate a credential immediately if it is exposed. After rotation, test a fetch
+and a push on a translation branch, then confirm that the webhook still causes
+Weblate to update.
+
+## Troubleshooting
+
+### Weblate shows an outdated source
+
+Confirm the Gitea webhook delivery, then update the repository from Weblate.
+Check that the component branch matches the version mapping and that there are
+no pending changes blocking a pull.
+
+### Weblate cannot push
+
+Check the component repository error, repository write permission, and branch
+name. Weblate must push to `translation/weblate-X.Y`, not to a protected release
+branch. Do not weaken release-branch protection to work around this error.
+
+### A component is locked
+
+Read the recorded repository error first. Correct authentication, connectivity,
+or a Git conflict, update the repository, and only then unlock it. Repeatedly
+unlocking without correcting the cause can lose or duplicate work.
+
+### A new module is missing
+
+Verify that `modules//locale/es_DO.po` exists on the translation branch,
+then run component discovery from the server-core component. A missing catalog
+must be added in Git before Weblate can discover it.
+
+### A PO check fails in CI
+
+Run the repository validator locally:
+
+```console
+python -m pip install polib
+python ci/validate_po.py
+```
+
+Fix duplicate messages, invalid syntax, plural forms, or malformed placeholders
+in Weblate or on the translation branch. Do not bypass the validator.
+
+## Recovery and audit checklist
+
+- Export or back up the Weblate database and application data with the normal
+ infrastructure backup process; Git alone does not retain suggestions,
+ comments, permissions, or translation memory.
+- Verify Weblate backups by restoring them in an isolated environment.
+- Keep the Gitea repository as the source of truth for released PO files.
+- Audit Weblate project access and repository credentials periodically.
+- Check that all four translation branches still exist and are not ahead with
+ unreviewed changes.
+- Confirm webhook delivery and one repository refresh after maintenance.
+- Record the pull request and deployed image/package version for every release.
+