From 26dfc83d7488695cb963d76116beb017ef9aa07c Mon Sep 17 00:00:00 2001 From: Conner Smith Date: Sat, 23 May 2026 21:47:39 -0500 Subject: [PATCH 1/3] fix: de-duplicate sidebar and document site structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sidebar in astro.config.mjs listed Guides/Templates/Tools/Case Studies twice, and its "Guides" autogenerate recursed into the module-0/ and phase-*/ subfolders that are also curated by hand — so every module and phase page appeared multiple times in the left nav. Convert "Guides" to an explicit landing + reference list so it no longer recurses into the curated Module/Phase sections, and remove the duplicated resource block. Each section now appears exactly once; the build is clean. Also add site/README.md documenting how the site is structured — including the nested src/content/docs/docs/ folders, the file-to-URL mapping, how to add a page, and how the sidebar is wired (autogenerate vs. explicit, and the duplication trap to avoid). CONTRIBUTING.md now points to it. --- CONTRIBUTING.md | 2 + site/README.md | 181 ++++++++++++++++++++++++++++++++++++++++++ site/astro.config.mjs | 45 +++++------ 3 files changed, 204 insertions(+), 24 deletions(-) create mode 100644 site/README.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e1bbb1c..93e5f29 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,6 +42,8 @@ All pull requests to `main` require review before merging. Every page on the website is a markdown file in this repo under `site/src/content/docs/docs/`. Adding a page is the same as editing one. +> **New to the site's structure?** [`site/README.md`](site/README.md) is the full reference — it explains where files go, how a file's path becomes its URL, why there are two nested `docs/` folders, and how the sidebar is wired (including how to avoid duplicate nav entries). The quick version is below. + **Easy path (no local setup):** 1. Browse to a similar page on the live site (e.g., an existing guide). diff --git a/site/README.md b/site/README.md new file mode 100644 index 0000000..90d9723 --- /dev/null +++ b/site/README.md @@ -0,0 +1,181 @@ +# OSL Playbook — Website + +This folder is the published website for the Tribal Data Sovereignty Cloud Playbook. It's an [Astro](https://astro.build/) site using the [Starlight](https://starlight.astro.build/) docs theme, deployed to GitHub Pages at: + +**https://open-sovereignty-lab.github.io/playbook/** + +Every page on the site is a file in this folder. Adding or editing a page means adding or editing a file here — no CMS, no database. This README explains where files go, how a file's location becomes its URL, and the one structural quirk that surprises everyone (`docs/docs/`). + +> **Just want to add a page?** Jump to [Adding a page](#adding-a-page). For the no-local-setup GitHub-web-editor path, see [`CONTRIBUTING.md`](../CONTRIBUTING.md). + +--- + +## The two kinds of pages + +There are exactly two kinds of pages, and they live in different places: + +| Kind | Lives in | Examples | When to use | +|------|----------|----------|-------------| +| **Marketing / standalone pages** | `src/pages/` | homepage (`/`), `/about`, the 404 page | One-off, custom-designed pages. Hand-built layouts. Rare. | +| **Documentation pages** | `src/content/docs/docs/` | every guide, template, tool, case study | **Almost everything you'll add.** Markdown content that shows up in the left sidebar. | + +**If you're adding playbook content, you want a documentation page.** That's the rest of this guide. + +--- + +## Why are there two `docs` folders? (`src/content/docs/docs/`) + +This is the part that confuses everyone. Yes, the path really is `.../content/docs/docs/...`, with `docs` twice. Each one means something different: + +``` +site/src/content/docs/docs/guides/module-0/index.md + ╰──┬──╯╰─┬─╯ + │ │ + (1) framework-required (2) our choice: the "/docs" URL section +``` + +**First `docs/` — required by the framework.** +Astro stores content "collections" at `src/content//`. Starlight's collection is named `docs`, so its root folder *must* be `src/content/docs/`. We can't rename this without reconfiguring the whole site. Think of it as plumbing. + +**Second `docs/` — our choice, and it sets the URL.** +By default Starlight would serve docs at the site **root** (`/guides/...`). But our root is already taken by the custom marketing homepage and `/about` (the `src/pages/` files above). To keep all playbook documentation tucked under a tidy `/docs/...` address — separate from the marketing pages — we put every doc inside a second `docs/` folder. **That second folder is literally the `/docs` you see in the URL.** + +So: + +- First `docs` = "this is the Starlight content collection" (plumbing, never changes) +- Second `docs` = "this is the `/docs` section of the website" (where your content goes) + +**You will always be working inside the second one: `src/content/docs/docs/`.** + +--- + +## File location → URL + +The folder path under `src/content/docs/docs/` becomes the URL path. A file named `index.md` becomes the folder's own page; any other filename becomes a page named after the file. Everything is prefixed with the site base `/playbook`. + +| File | Live URL | +|------|----------| +| `src/content/docs/docs/index.mdx` | `/playbook/docs/` | +| `src/content/docs/docs/guides/index.md` | `/playbook/docs/guides/` | +| `src/content/docs/docs/guides/example-guide.md` | `/playbook/docs/guides/example-guide/` | +| `src/content/docs/docs/guides/module-0/index.md` | `/playbook/docs/guides/module-0/` | +| `src/content/docs/docs/guides/module-0/glossary.md` | `/playbook/docs/guides/module-0/glossary/` | +| `src/content/docs/docs/templates/example-template.md` | `/playbook/docs/templates/example-template/` | + +The four top-level content sections are: + +- `guides/` — long-form guidance, plus the structured **Module** and **Phase** material (e.g. `guides/module-0/`, `guides/phase-1/`) +- `templates/` — reusable legal/technical templates +- `tools/` — calculators and utilities +- `case-studies/` — real-world tribal examples + +> **A folder needs an `index.md`** to have its own landing page (e.g. `guides/module-0/index.md` is the Module 0 overview). Without one, the folder still works as a container but `/docs/guides/module-0/` has no page of its own. + +--- + +## Adding a page + +1. **Pick the right section folder** under `src/content/docs/docs/` (`guides/`, `templates/`, `tools/`, or `case-studies/`). For a multi-page topic, make a subfolder (like `module-0/`) with its own `index.md`. + +2. **Create a `.md` file** there. The fastest start is to copy an existing example in the same section (`example-guide.md`, `example-template.md`, etc.) and replace its contents. + +3. **Add the required frontmatter** at the very top. The build **fails** without `title` and `description`: + + ```markdown + --- + title: Data Classification for Tribal Nations + description: How to classify tribal data by sensitivity before moving it to the cloud. + sidebar: + order: 2 # optional — controls position within its sidebar group (lower = higher up) + label: Data Classes # optional — shorter label for the sidebar (defaults to title) + --- + + Your content starts here, in normal Markdown. + ``` + +4. **Make it appear in the sidebar.** Where it shows up depends on the section — see [The sidebar](#the-sidebar) below. For `templates/`, `tools/`, and `case-studies/`, new pages appear **automatically**. For `guides/` Module/Phase material, you must add the page to the sidebar config by hand. + +5. **Link to repo files** (Terraform, `.docx` legal templates, etc.) using raw GitHub URLs — see `templates/example-template.md` for the pattern. + +6. **Open a pull request.** The PR build validates your frontmatter. After a maintainer merges, the live site updates in ~2 minutes. + +--- + +## The sidebar + +The left-hand navigation is configured in [`astro.config.mjs`](./astro.config.mjs), in the `sidebar:` array. There are **two ways** a section gets its pages, and mixing them up causes duplicate entries (this has bitten us before): + +**1. Autogenerated** — Starlight lists every page in a directory automatically: + +```js +{ label: "Templates", autogenerate: { directory: "docs/templates" } }, +``` + +Drop a new file into `templates/` and it shows up — no config change needed. We use this for **Templates, Tools, and Case Studies**. + +**2. Explicit list** — you name each page (and its order) by hand: + +```js +{ + label: "Module 0: Sovereignty in the Digital Age", + items: [ + { slug: "docs/guides/module-0" }, // the index.md + { slug: "docs/guides/module-0/tribal-sovereignty" }, + // ... + ], +}, +``` + +We use this for the **Module 0** and **Phase 1–3** sections so we control the exact teaching order. When you add a page under `module-0/` or a phase, **add its `slug` to this list** or it won't appear. + +> ⚠️ **The duplication gotcha.** `autogenerate` recurses into *every* subfolder. Because `module-0/` and `phase-*/` live inside `guides/`, autogenerating `docs/guides` would re-list all of that Module/Phase content that we already list by hand — showing each page twice. That's why `Guides` is an **explicit two-item list** (its landing page + the contributor reference), *not* an autogenerate. **Don't add `{ autogenerate: { directory: "docs/guides" } }`** — it will duplicate the whole Module/Phase tree. +> +> Rule of thumb: a given directory should be covered by **either** an autogenerate **or** explicit items — never both. + +--- + +## Running it locally (optional) + +You don't need this to add a page — the GitHub web editor + PR flow works fine. But to preview changes on your own machine: + +```bash +cd site +npm install # one time +npm run dev # serve at http://localhost:4321/playbook/ +``` + +Other commands: + +| Command | What it does | +|---------|--------------| +| `npm run dev` | Live-reloading local preview | +| `npm run build` | Production build into `dist/` — run this to catch frontmatter/slug errors before pushing | +| `npm run preview` | Serve the built `dist/` to check the real output | + +Deployment is automatic: merging to `main` triggers the GitHub Actions workflow in [`.github/workflows/deploy.yml`](../.github/workflows/deploy.yml), which builds the site and publishes it to GitHub Pages. + +--- + +## Folder map + +``` +site/ +├── astro.config.mjs # site config + the sidebar definition (edit this to change nav) +├── package.json # dependencies and npm scripts +├── public/ # static files served as-is (favicon, etc.) +└── src/ + ├── pages/ # standalone pages: homepage, /about, 404 + ├── components/ # reusable building blocks for the standalone pages + ├── styles/ # theme.css — site-wide colors and typography + ├── content.config.ts # registers the Starlight "docs" collection (don't edit casually) + └── content/ + └── docs/ # (1) the Starlight collection root — required name + └── docs/ # (2) the "/docs" URL section — YOUR CONTENT GOES HERE + ├── index.mdx # the /docs landing page + ├── guides/ # guides + Module/Phase material + ├── templates/ + ├── tools/ + └── case-studies/ +``` + +When in doubt, you're almost always adding a `.md` file inside `src/content/docs/docs/
/`. diff --git a/site/astro.config.mjs b/site/astro.config.mjs index 78a0cd1..c589fb0 100644 --- a/site/astro.config.mjs +++ b/site/astro.config.mjs @@ -23,11 +23,7 @@ export default defineConfig({ baseUrl: 'https://github.com/Open-Sovereignty-Lab/playbook/edit/main/site/', }, sidebar: [ - { label: 'Guides', autogenerate: { directory: 'docs/guides' } }, - { label: 'Templates', autogenerate: { directory: 'docs/templates' } }, - { label: 'Tools', autogenerate: { directory: 'docs/tools' } }, - { label: 'Case Studies', autogenerate: { directory: 'docs/case-studies' } }, - // ------------------------------------------------------------------ + // ------------------------------------------------------------------ // MODULE 0: Sovereignty in the Digital Age // ------------------------------------------------------------------ { @@ -51,11 +47,11 @@ export default defineConfig({ collapsed: true, items: [ { slug: "docs/guides/phase-1" }, // index.md (Overview) - // { slug: "docs/phase-1/organizational-readiness" }, - // { slug: "docs/phase-1/data-classification" }, - // { slug: "docs/phase-1/policy-legal-framework" }, - // { slug: "docs/phase-1/ai-literacy" }, - // { slug: "docs/phase-1/procurement-readiness" }, + // { slug: "docs/guides/phase-1/organizational-readiness" }, + // { slug: "docs/guides/phase-1/data-classification" }, + // { slug: "docs/guides/phase-1/policy-legal-framework" }, + // { slug: "docs/guides/phase-1/ai-literacy" }, + // { slug: "docs/guides/phase-1/procurement-readiness" }, ], }, @@ -82,24 +78,25 @@ export default defineConfig({ }, // ------------------------------------------------------------------ - // EXISTING RESOURCE SECTIONS (preserved from current config) + // RESOURCE SECTIONS + // + // The Module 0 and Phase sections above already curate everything + // under docs/guides/. "Guides" is therefore listed explicitly (just + // its landing + reference page) instead of autogenerated -- an + // autogenerate of docs/guides would recurse into module-0/ and + // phase-*/ and re-list every page already shown above, which is what + // produced the duplicated sidebar entries. // ------------------------------------------------------------------ { label: "Guides", - autogenerate: { directory: "docs/guides" }, - }, - { - label: "Templates", - autogenerate: { directory: "docs/templates" }, - }, - { - label: "Tools", - autogenerate: { directory: "docs/tools" }, - }, - { - label: "Case Studies", - autogenerate: { directory: "docs/case-studies" }, + items: [ + { slug: "docs/guides" }, // Guides landing (index.md) + { slug: "docs/guides/example-guide" }, // Contributor reference page + ], }, + { label: "Templates", autogenerate: { directory: "docs/templates" } }, + { label: "Tools", autogenerate: { directory: "docs/tools" } }, + { label: "Case Studies", autogenerate: { directory: "docs/case-studies" } }, ], }), ], From a017572be30bcb998c10bf5624fadfd0c92cc523 Mon Sep 17 00:00:00 2001 From: Conner Smith Date: Sat, 23 May 2026 22:11:22 -0500 Subject: [PATCH 2/3] refactor: drive Module/Phase sidebar groups from autogenerate The initial fix removed the duplication but kept the Module 0 and Phase groups as hand-listed `items: [{ slug }]` arrays, which meant adding a page still required editing astro.config.mjs -- the same friction that led to the duplicate entries in the first place. Switch those groups to `autogenerate` with a custom label, so their pages and ordering come entirely from the folder and each page's sidebar.order frontmatter. The page slugs already carried correct order values, so the rendered sidebar is identical (verified: 18 links, no duplicates, original teaching order preserved) -- but contributors no longer touch this config to add, remove, or reorder a page within a section. Update site/README.md's sidebar section to describe the autogenerate-driven model and when (rarely) the config needs editing. --- site/README.md | 47 ++++++++++++++++++++++---------- site/astro.config.mjs | 62 ++++++++++++++----------------------------- 2 files changed, 53 insertions(+), 56 deletions(-) diff --git a/site/README.md b/site/README.md index 90d9723..51546cf 100644 --- a/site/README.md +++ b/site/README.md @@ -93,7 +93,7 @@ The four top-level content sections are: Your content starts here, in normal Markdown. ``` -4. **Make it appear in the sidebar.** Where it shows up depends on the section — see [The sidebar](#the-sidebar) below. For `templates/`, `tools/`, and `case-studies/`, new pages appear **automatically**. For `guides/` Module/Phase material, you must add the page to the sidebar config by hand. +4. **It appears in the sidebar automatically.** Every section (including the Module 0 and Phase groups) is autogenerated from its folder, so a new file shows up on its own — ordered by `sidebar.order`. You do **not** edit `astro.config.mjs` to add a page. See [The sidebar](#the-sidebar) for the one exception and the reason behind it. 5. **Link to repo files** (Terraform, `.docx` legal templates, etc.) using raw GitHub URLs — see `templates/example-template.md` for the pattern. @@ -103,34 +103,53 @@ The four top-level content sections are: ## The sidebar -The left-hand navigation is configured in [`astro.config.mjs`](./astro.config.mjs), in the `sidebar:` array. There are **two ways** a section gets its pages, and mixing them up causes duplicate entries (this has bitten us before): +The left-hand navigation is configured in [`astro.config.mjs`](./astro.config.mjs), in the `sidebar:` array. -**1. Autogenerated** — Starlight lists every page in a directory automatically: +**The important thing to understand: in almost every case you do _not_ touch this file to add a page.** The sidebar is driven by the *folders and frontmatter*, not by a hand-maintained list. Adding a page is just adding a `.md` file with `title`, `description`, and (optionally) `sidebar.order`. + +That works because every section uses Starlight's **`autogenerate`**, which reflects a folder into the nav automatically: ```js { label: "Templates", autogenerate: { directory: "docs/templates" } }, ``` -Drop a new file into `templates/` and it shows up — no config change needed. We use this for **Templates, Tools, and Case Studies**. +Drop a file into `templates/` → it appears, ordered by its `sidebar.order`. No config change. -**2. Explicit list** — you name each page (and its order) by hand: +The Module 0 and Phase groups work the same way — they just keep a custom label on top of the autogenerated folder: ```js { - label: "Module 0: Sovereignty in the Digital Age", - items: [ - { slug: "docs/guides/module-0" }, // the index.md - { slug: "docs/guides/module-0/tribal-sovereignty" }, - // ... - ], + label: "Module 0: Sovereignty in the Digital Age", // pretty label we choose + autogenerate: { directory: "docs/guides/module-0" }, // pages come from the folder }, ``` -We use this for the **Module 0** and **Phase 1–3** sections so we control the exact teaching order. When you add a page under `module-0/` or a phase, **add its `slug` to this list** or it won't appear. +So to add page `0.5` to Module 0, you create `guides/module-0/whatever.md` with `sidebar.order: 7` — and you're done. **You never edit `astro.config.mjs` for that.** + +### When *do* you edit the config? + +Only for structural changes, not content: + +- **Adding a brand-new top-level group** with its own label (e.g. a future "Module 1") — add one `{ label, autogenerate }` block. +- **Renaming a group label.** + +Adding, removing, or reordering *pages within an existing section* is always done in frontmatter. + +### The one explicit list, and the duplication gotcha + +`Guides` is the single exception — an explicit two-item list (its landing page + the contributor reference), not an autogenerate: + +```js +{ label: "Guides", items: [ { slug: "docs/guides" }, { slug: "docs/guides/example-guide" } ] }, +``` + +Here's why, and it's the trap that caused the bug this all started with: -> ⚠️ **The duplication gotcha.** `autogenerate` recurses into *every* subfolder. Because `module-0/` and `phase-*/` live inside `guides/`, autogenerating `docs/guides` would re-list all of that Module/Phase content that we already list by hand — showing each page twice. That's why `Guides` is an **explicit two-item list** (its landing page + the contributor reference), *not* an autogenerate. **Don't add `{ autogenerate: { directory: "docs/guides" } }`** — it will duplicate the whole Module/Phase tree. +> ⚠️ **`autogenerate` recurses into _every_ subfolder.** `module-0/` and `phase-*/` live *inside* `guides/`. So `autogenerate: { directory: "docs/guides" }` would pull in the entire Module/Phase tree — which is *already* shown by the Module 0 and Phase groups above — listing every one of those pages twice. That's exactly what happened before: a `docs/guides` autogenerate sitting next to hand-maintained Module/Phase groups. > -> Rule of thumb: a given directory should be covered by **either** an autogenerate **or** explicit items — never both. +> **Rule of thumb: each directory is owned by exactly one sidebar entry — never autogenerate a folder *and* its parent, and never autogenerate a folder you also list by hand.** + +Because `module-0/` and `phase-*/` already have their own groups, `Guides` only needs its two loose top-level pages, so it's listed explicitly rather than autogenerating `docs/guides`. --- diff --git a/site/astro.config.mjs b/site/astro.config.mjs index c589fb0..ec6899a 100644 --- a/site/astro.config.mjs +++ b/site/astro.config.mjs @@ -24,68 +24,46 @@ export default defineConfig({ }, sidebar: [ // ------------------------------------------------------------------ - // MODULE 0: Sovereignty in the Digital Age + // CURATED LEARNING PATH (Module 0 + Phases) + // + // Each group keeps a hand-written label, but its pages are pulled in + // with `autogenerate` and ordered by each page's `sidebar.order` + // frontmatter. That means adding or reordering a page is done in the + // page's frontmatter -- this config is NOT touched. + // + // Do NOT switch these back to manual `items: [{ slug }]` lists, and do + // NOT autogenerate their shared parent (docs/guides): either approach + // lists the same pages a second time and duplicates the sidebar. // ------------------------------------------------------------------ { label: "Module 0: Sovereignty in the Digital Age", - items: [ - { slug: "docs/guides/module-0" }, // index.md (Overview) - { slug: "docs/guides/module-0/tribal-sovereignty" }, // 0.1 - { slug: "docs/guides/module-0/data-sovereignty" }, // 0.2 - { slug: "docs/guides/module-0/digital-self-determination" }, // 0.3 - { slug: "docs/guides/module-0/ocap-analysis" }, // OCAP deep-dive - { slug: "docs/guides/module-0/digital-colonization" }, // 0.4 - { slug: "docs/guides/module-0/glossary" }, // Glossary - ], + autogenerate: { directory: "docs/guides/module-0" }, }, - - // ------------------------------------------------------------------ - // PHASE 1: PRE-WORK (placeholder -- add pages as content is ready) - // ------------------------------------------------------------------ { label: "Phase 1: Pre-Work", collapsed: true, - items: [ - { slug: "docs/guides/phase-1" }, // index.md (Overview) - // { slug: "docs/guides/phase-1/organizational-readiness" }, - // { slug: "docs/guides/phase-1/data-classification" }, - // { slug: "docs/guides/phase-1/policy-legal-framework" }, - // { slug: "docs/guides/phase-1/ai-literacy" }, - // { slug: "docs/guides/phase-1/procurement-readiness" }, - ], + autogenerate: { directory: "docs/guides/phase-1" }, }, - - // ------------------------------------------------------------------ - // PHASE 2: EXECUTION (placeholder) - // ------------------------------------------------------------------ { label: "Phase 2: Execution", collapsed: true, - items: [ - { slug: "docs/guides/phase-2" }, - ], + autogenerate: { directory: "docs/guides/phase-2" }, }, - - // ------------------------------------------------------------------ - // PHASE 3: MONITORING AND EVALUATION (placeholder) - // ------------------------------------------------------------------ { label: "Phase 3: Monitoring and Evaluation", collapsed: true, - items: [ - { slug: "docs/guides/phase-3" }, - ], + autogenerate: { directory: "docs/guides/phase-3" }, }, // ------------------------------------------------------------------ // RESOURCE SECTIONS // - // The Module 0 and Phase sections above already curate everything - // under docs/guides/. "Guides" is therefore listed explicitly (just - // its landing + reference page) instead of autogenerated -- an - // autogenerate of docs/guides would recurse into module-0/ and - // phase-*/ and re-list every page already shown above, which is what - // produced the duplicated sidebar entries. + // "Guides" is an explicit landing + reference list, NOT an + // autogenerate of docs/guides -- that directory contains the module-0/ + // and phase-*/ folders above, so autogenerating it would list every + // module and phase page a second time. Templates / Tools / Case + // Studies are flat folders, so they autogenerate cleanly: drop a file + // in and it appears. // ------------------------------------------------------------------ { label: "Guides", From 63298ea447aa47a0616748b3fe865b8bff61818f Mon Sep 17 00:00:00 2001 From: Conner Smith Date: Sat, 23 May 2026 22:18:27 -0500 Subject: [PATCH 3/3] docs: explain sidebar frontmatter controls; label module-0 index "Overview" Add a "Controlling how a page looks in the sidebar" section to site/README.md covering title vs sidebar.label, sidebar.order (with gap advice), and badges, plus the index-vs-group label pattern. Set sidebar.label: Overview on guides/module-0/index.md so the Module 0 group's first entry reads "Overview" instead of repeating the full module title. --- site/README.md | 29 +++++++++++++++++++ .../docs/docs/guides/module-0/index.md | 1 + 2 files changed, 30 insertions(+) diff --git a/site/README.md b/site/README.md index 51546cf..256ee57 100644 --- a/site/README.md +++ b/site/README.md @@ -126,6 +126,35 @@ The Module 0 and Phase groups work the same way — they just keep a custom labe So to add page `0.5` to Module 0, you create `guides/module-0/whatever.md` with `sidebar.order: 7` — and you're done. **You never edit `astro.config.mjs` for that.** +### Controlling how a page looks in the sidebar (from frontmatter) + +Since the sidebar is autogenerated, the **page's own frontmatter** is where you set its label and position. The relevant keys live under `sidebar:`: + +```markdown +--- +title: OCAP® Principles in Practice # the

and browser tab title +description: How OCAP maps to cloud controls. # required; used for SEO/social +sidebar: + order: 4 # position within the group; lower = higher up (ties break alphabetically) + label: OCAP Analysis # the text shown in the sidebar; defaults to `title` if omitted + badge: New # optional little badge next to the link +--- +``` + +Key points: + +- **`title` vs `sidebar.label`.** `title` is the big heading on the page itself. `sidebar.label` is only the nav text — set it when the full title is too long for the sidebar, or would read awkwardly there. If you omit `label`, the sidebar just uses `title`. +- **`sidebar.order`** controls position *within that page's group*. Numbers don't need to be contiguous (0, 1, 2, 5, 10 is fine) — leave gaps so you can insert pages later without renumbering. Pages with no `order` sort after ordered ones, alphabetically. +- **A folder's `index.md` is a page too**, and it shows up as the first item *inside* its group. Because the group already has a label (e.g. "Module 0: Sovereignty in the Digital Age"), give the index a short `sidebar.label` so the first item doesn't repeat the whole group name. That's why `guides/module-0/index.md` uses: + + ```markdown + sidebar: + order: 0 + label: Overview + ``` + + → the group reads **"Module 0: Sovereignty in the Digital Age"** with **"Overview"** as its first entry, instead of the title appearing twice. + ### When *do* you edit the config? Only for structural changes, not content: diff --git a/site/src/content/docs/docs/guides/module-0/index.md b/site/src/content/docs/docs/guides/module-0/index.md index 165a345..5e5d1d4 100644 --- a/site/src/content/docs/docs/guides/module-0/index.md +++ b/site/src/content/docs/docs/guides/module-0/index.md @@ -3,6 +3,7 @@ title: "Module 0: Sovereignty in the Digital Age" description: "The foundational framing for the entire Playbook. Establishes what tribal sovereignty means, why it extends to data and digital systems, and how it governs every decision that follows." sidebar: order: 0 + label: Overview --- This module is the foundation for everything that follows in the Playbook. Before we talk about AI tools, cloud platforms, procurement, or technical architecture, we need to establish the principle that governs all of those decisions: tribal sovereignty is inherent, it is not granted, and it extends into every domain where tribal nations exercise self-governance, including the digital.