Docs publishing to ReadMe
The docs/ tree is authored in forge-core in ReadMe bi-directional sync format (category folders + _order.yaml + title/summary frontmatter) and published to a ReadMe project served from https://docs.forgeplatform.software. forge-core stays the single source of truth.
ReadMe projects are Git-backed, so the legacy upload API (
rdme docs upload) is not available. Content reaches ReadMe only through bi-directional Git sync with a connected repository.
Flow
flowchart TB core["forge-core/docs (full ADRs, PRIVATE)"] core -->|"92-mirror-docs.yml: redact, snapshot commit"| docs["forge-docs (redacted, PUBLIC, ReadMe-connected)"] docs -->|"ReadMe Git sync (automatic)"| readme["ReadMe project"] readme --> domain["docs.forgeplatform.software"]
92-mirror-docs.yml(runs in forge-core) copies the redacteddocs/tree into forge-docs as a normal commit. No API key, no upload step. ReadMe only syncs the branch whose name matches its Main Version, so the mirror publishes to that branch (MIRROR_BRANCH, e.g.v1.0) — notmain— layering onto ReadMe's initial commit so a merge base always exists.- forge-docs is connected to ReadMe via bi-directional Git sync, so ReadMe ingests each commit automatically. Redaction happens once, in the mirror, so the connected repo is always public-safe.
Because ReadMe co-owns the connected repo, the mirror commits normally (no force-push / history rewrite), and we author only in forge-core, never in the ReadMe UI, which keeps the sync effectively one-way and conflict-free.
Repository layout (bi-directional sync)
ReadMe maps folders to categories and uses _order.yaml for ordering. Each page's filename is its URL slug. This is the layout of the ReadMe-connected mirror (forge-docs):
forge-docs/
├── assets/ # images + perf data; OUTSIDE docs/ so it is not a category
└── docs/
├── _order.yaml # category order
├── getting-started/
│ ├── _order.yaml # page order within the category
│ ├── welcome.md
│ └── ...
├── architecture-guides/
│ ├── _order.yaml
│ ├── security.md
│ └── ...
├── performance/ # own category; runs nested under performance.md
│ ├── _order.yaml
│ ├── performance.md
│ └── perf-test-plan.md # child of performance.md (via _order.yaml)
└── architecture-decisions/
├── _order.yaml
└── 0001-record-architecture-decisions.mdIn forge-core the images live under docs/assets/; the mirror relocates them to the repo root (/assets) so ReadMe never treats assets as a category. ReadMe only nests one folder level deep — every folder under docs/ is a category, so a "sub-category" is just another top-level category folder. Parent/child page hierarchy within a category is expressed by indentation in _order.yaml, not by subfolders. Page frontmatter:
---
title: Platform security posture
summary: Security controls, accepted risks, and client responsibilities.
---One-time manual setup
These require ReadMe account, forge-docs repository, and DNS access and are not automated:
- Connect the repo - the repo ReadMe syncs with must be truly empty (no commits or files) at connection time. Empty forge-docs, then in ReadMe under Settings > Git Connection install the ReadMe Sync GitHub App and select forge-docs. On connect, ReadMe pushes an initial commit to a branch named after its Main Version (e.g.
v1.0); make that branch the repo default and set the mirror'sMIRROR_BRANCHto match. The mirror then populates it on the next run. - Custom domain - in ReadMe under Configuration > Custom Domain set
docs.forgeplatform.software, then add the provided CNAME (target<subdomain-hash>.readmessl.com) and any TXT validation record to theforgeplatform.softwareRoute53 hosted zone. ReadMe auto-provisions SSL via Cloudflare. - Retire GitHub Pages - set the forge-docs repository's Pages source to "None".
Updated 10 days ago