diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..264d2d4
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,42 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: github-actions # See documentation for possible values
+ directory: / # Location of package manifests
+ labels:
+ - dependencies
+ - github-actions
+ schedule:
+ interval: weekly
+ cooldown:
+ default-days: 7
+ groups:
+ # Bundle low-risk minor and patch bumps into one PR; majors arrive alone
+ # so they can be reviewed by hand.
+ actions-minor-and-patch:
+ patterns:
+ - "*"
+ update-types:
+ - minor
+ - patch
+
+ - package-ecosystem: pip # Build toolchain pinned in requirements.txt
+ directory: /
+ labels:
+ - dependencies
+ - python
+ schedule:
+ interval: weekly
+ cooldown:
+ default-days: 7
+ groups:
+ python-minor-and-patch:
+ patterns:
+ - "*"
+ update-types:
+ - minor
+ - patch
diff --git a/.github/linters/.codespellrc b/.github/linters/.codespellrc
new file mode 100644
index 0000000..512b4cb
--- /dev/null
+++ b/.github/linters/.codespellrc
@@ -0,0 +1,3 @@
+[codespell]
+skip = ./.github/linters
+ignore-words-list = afterall,skelton
diff --git a/.github/linters/.markdown-lint.yml b/.github/linters/.markdown-lint.yml
new file mode 100644
index 0000000..4c0f98c
--- /dev/null
+++ b/.github/linters/.markdown-lint.yml
@@ -0,0 +1,29 @@
+###########################
+## Markdown Linter rules ##
+###########################
+
+# Linter rules doc:
+# - https://github.com/DavidAnson/markdownlint
+
+###############
+# Rules by id #
+###############
+MD004: false # Unordered list style
+MD007:
+ indent: 2 # Unordered list indentation
+MD013:
+ line_length: 3000 # Line length
+MD025:
+ front_matter_title: "" # Allow a body H1 alongside the front matter title
+MD026:
+ punctuation: ".,;:!。,;:" # List of not allowed
+MD029: false # Ordered list item prefix
+MD033: false # Allow inline HTML
+MD036: false # Emphasis used instead of a heading
+MD041: false # First line in file should be a top level heading, PULL_REQUEST_TEMPLATE.md is an exception
+MD060: false # Table column style — content mixes compact and aligned tables
+
+#################
+# Rules by tags #
+#################
+blank_lines: false # Error on blank lines
diff --git a/.github/linters/.powershell-psscriptanalyzer.psd1 b/.github/linters/.powershell-psscriptanalyzer.psd1
new file mode 100644
index 0000000..52f0ee5
--- /dev/null
+++ b/.github/linters/.powershell-psscriptanalyzer.psd1
@@ -0,0 +1,55 @@
+# PSScriptAnalyzer settings — the enforcement mechanism for the PowerShell coding
+# standard (src/docs/Coding-Standards/PowerShell/index.md). The standard is the
+# source of truth; every rule configured here is derived from it. Change a rule by
+# changing the standard first, then reflect it here — never the other way around.
+#
+# super-linter discovers this file automatically as POWERSHELL_CONFIG_FILE
+# (.powershell-psscriptanalyzer.psd1) under .github/linters.
+@{
+ # Run the full default rule set — approved verbs, singular nouns, alias bans,
+ # $null-on-the-left comparisons, Invoke-Expression, unused variables, and the
+ # rest — then tighten the formatting rules below to match the standard.
+ IncludeDefaultRules = $true
+
+ # Gate on errors and warnings; both map to rules the standard requires.
+ Severity = @('Error', 'Warning')
+
+ Rules = @{
+ # One True Brace Style: opening brace on the statement line, closing brace
+ # on its own line with no blank line before it. NewLineAfter stays false on
+ # the close brace so else / elseif / catch / finally sit on the same line as
+ # the preceding brace ("} else {"), as the standard requires.
+ PSPlaceOpenBrace = @{
+ Enable = $true
+ OnSameLine = $true
+ NewLineAfter = $true
+ IgnoreOneLineBlock = $true
+ }
+ PSPlaceCloseBrace = @{
+ Enable = $true
+ NewLineAfter = $false
+ IgnoreOneLineBlock = $true
+ NoEmptyLineBefore = $true
+ }
+
+ # Indent with four spaces, never tabs.
+ PSUseConsistentIndentation = @{
+ Enable = $true
+ Kind = 'space'
+ IndentationSize = 4
+ PipelineIndentation = 'IncreaseIndentationForFirstPipeline'
+ }
+
+ # One space around operators and after commas, and consistent brace and
+ # parenthesis spacing.
+ PSUseConsistentWhitespace = @{
+ Enable = $true
+ CheckInnerBrace = $true
+ CheckOpenBrace = $true
+ CheckOpenParen = $true
+ CheckOperator = $true
+ CheckPipe = $true
+ CheckSeparator = $true
+ }
+ }
+}
diff --git a/.github/linters/.textlintrc b/.github/linters/.textlintrc
new file mode 100644
index 0000000..db48de8
--- /dev/null
+++ b/.github/linters/.textlintrc
@@ -0,0 +1,513 @@
+{
+ "filters": {
+ "comments": true
+ },
+ "rules": {
+ "terminology": {
+ "defaultTerms": false,
+ "terms": [
+ "Airbnb",
+ "Android",
+ "AppleScript",
+ "AppVeyor",
+ "AVA",
+ "BrowserStack",
+ "Browsersync",
+ "Codecov",
+ "CodePen",
+ "CodeSandbox",
+ "DefinitelyTyped",
+ "EditorConfig",
+ "ESLint",
+ "GitHub",
+ "GraphQL",
+ "GraphiQL",
+ "iOS",
+ "JavaScript",
+ "JetBrains",
+ "jQuery",
+ "LinkedIn",
+ "Lodash",
+ "MacBook",
+ "Markdown",
+ "OpenType",
+ "PayPal",
+ "PhpStorm",
+ "PowerShell",
+ "PlayStation",
+ "RubyMine",
+ "Sass",
+ "SemVer",
+ "TypeScript",
+ "UglifyJS",
+ "Wasm",
+ "WebAssembly",
+ "WebStorm",
+ "WordPress",
+ "YouTube",
+ [
+ "Common[ .]js",
+ "CommonJS"
+ ],
+ [
+ "JSDocs?",
+ "JSDoc"
+ ],
+ [
+ "Node[ .]js",
+ "Node.js"
+ ],
+ [
+ "React[ .]js",
+ "React"
+ ],
+ [
+ "SauceLabs",
+ "Sauce Labs"
+ ],
+ [
+ "StackOverflow",
+ "Stack Overflow"
+ ],
+ [
+ "styled ?components",
+ "styled-components"
+ ],
+ [
+ "HTTP[ /]2(?:\\.0)?",
+ "HTTP/2"
+ ],
+ [
+ "OS X",
+ "macOS"
+ ],
+ [
+ "Mac ?OS",
+ "macOS"
+ ],
+ [
+ "a npm",
+ "an npm"
+ ],
+ "ECMAScript",
+ [
+ "ES2015",
+ "ES6"
+ ],
+ [
+ "ES7",
+ "ES2016"
+ ],
+ "3D",
+ [
+ "3-D",
+ "3D"
+ ],
+ "Ajax",
+ "API",
+ "APIs",
+ "API's",
+ [
+ "(?
+[CmdletBinding()]
+param()
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference = 'Stop'
+
+$Root = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
+$Docs = Join-Path $Root 'src/docs'
+
+function ConvertTo-Slug {
+ param([string]$Heading)
+ # Mirror the site's Markdown TOC slugifier (python-markdown default): drop
+ # non-ASCII, remove punctuation except word characters / whitespace / hyphen,
+ # lowercase, then collapse whitespace and hyphen runs into a single hyphen.
+ $ascii = -join ([char[]] $Heading | Where-Object { [int] $_ -lt 128 })
+ $clean = ($ascii -replace '[^\w\s-]', '').Trim().ToLowerInvariant()
+ return ($clean -replace '[\s-]+', '-')
+}
+
+function Get-HeadingSlug {
+ param([string]$Path)
+ # The anchor slugs a page exposes, matching the duplicate-slug suffixing
+ # ('_1', '_2', ...) the Markdown processor applies to repeated headings.
+ $slugs = [System.Collections.Generic.List[string]]::new()
+ $seen = @{}
+ $inFence = $false
+ foreach ($line in [System.IO.File]::ReadAllLines($Path)) {
+ if ($line -match '^\s*```') { $inFence = -not $inFence; continue }
+ if ($inFence) { continue }
+ if ($line -match '^#{1,6}\s+(.+?)\s*$') {
+ $base = ConvertTo-Slug $matches[1]
+ if (-not $base) { continue }
+ if ($seen.ContainsKey($base)) { $seen[$base]++; $slugs.Add("${base}_$($seen[$base])") }
+ else { $seen[$base] = 0; $slugs.Add($base) }
+ }
+ }
+ return $slugs
+}
+
+# Parse each target file's anchors once.
+$slugCache = @{}
+function Get-CachedSlug {
+ param([string]$Path)
+ if (-not $slugCache.ContainsKey($Path)) { $slugCache[$Path] = Get-HeadingSlug $Path }
+ return $slugCache[$Path]
+}
+
+$linkPattern = '\[[^\]]*\]\(([^)]+)\)'
+$broken = [System.Collections.Generic.List[string]]::new()
+
+foreach ($file in (Get-ChildItem -LiteralPath $Docs -Recurse -File -Filter *.md | Sort-Object FullName)) {
+ $rel = ($file.FullName.Substring($Root.Length).TrimStart('\', '/')) -replace '\\', '/'
+ $lines = [System.IO.File]::ReadAllLines($file.FullName)
+ $inFence = $false
+ for ($n = 0; $n -lt $lines.Count; $n++) {
+ $line = $lines[$n]
+ if ($line -match '^\s*```') { $inFence = -not $inFence; continue }
+ if ($inFence) { continue }
+ # Remove inline code spans so links shown as examples are not validated.
+ $scrubbed = $line -replace '`[^`]*`', ''
+ foreach ($m in [regex]::Matches($scrubbed, $linkPattern)) {
+ $target = $m.Groups[1].Value.Trim() -replace '\s+"[^"]*"$', '' # strip optional link title
+ if (-not $target) { continue }
+ if ($target -match '^(https?:|mailto:|tel:|//)') { continue }
+ $lineNo = $n + 1
+ $path, $frag = $target -split '#', 2
+ if (-not $path) {
+ if ($frag -and ($frag -notin (Get-CachedSlug $file.FullName))) {
+ $broken.Add("${rel}:${lineNo}: '#$frag' - no heading with that anchor on this page")
+ }
+ continue
+ }
+ if ($path.StartsWith('/')) { continue } # absolute site path - not resolvable here
+ $resolved = [System.IO.Path]::GetFullPath((Join-Path $file.DirectoryName $path))
+ if (-not (Test-Path -LiteralPath $resolved)) {
+ $broken.Add("${rel}:${lineNo}: '$target' - target does not exist")
+ continue
+ }
+ if ($frag -and $resolved.EndsWith('.md') -and ($frag -notin (Get-CachedSlug $resolved))) {
+ $broken.Add("${rel}:${lineNo}: '$target' - no heading '#$frag' in the target file")
+ }
+ }
+ }
+}
+
+if ($broken.Count -eq 0) {
+ Write-Output 'All documentation links resolve.'
+ exit 0
+}
+Write-Output "Broken documentation links ($($broken.Count)):"
+$broken | Sort-Object | ForEach-Object { Write-Output " - $_" }
+exit 1
diff --git a/.github/scripts/Update-DocumentationIndex.ps1 b/.github/scripts/Update-DocumentationIndex.ps1
new file mode 100644
index 0000000..26d5599
--- /dev/null
+++ b/.github/scripts/Update-DocumentationIndex.ps1
@@ -0,0 +1,167 @@
+#!/usr/bin/env pwsh
+#Requires -Version 7.0
+<#
+.SYNOPSIS
+ Update each section index.md with a table generated from page front matter.
+
+.DESCRIPTION
+ Every documentation page declares 'title' and 'description' in YAML front
+ matter. Each index.md that contains the INDEX markers gets an auto-generated
+ table of the documents at its level - subsections for the root, pages for a
+ section - ordered to match the navigation in zensical.toml.
+
+ Run with no arguments to update the index files in place. Run with -Check to
+ verify they are up to date, changing nothing and exiting non-zero on drift.
+
+ Glue across the ecosystem is PowerShell. PowerShell has no built-in TOML
+ parser, so the navigation order is derived by reading the ordered "*.md"
+ path strings from the nav array in zensical.toml - the only place .md paths
+ appear in that file.
+
+.EXAMPLE
+ ./Update-DocumentationIndex.ps1
+ Updates every section index.md in place from the current front matter.
+
+.EXAMPLE
+ ./Update-DocumentationIndex.ps1 -Check
+ Verifies the indexes are current without writing; exits non-zero on drift.
+ This is the mode the CI build job runs.
+#>
+[CmdletBinding()]
+param(
+ # Verify the indexes are up to date without writing; exit non-zero on drift.
+ [Parameter()]
+ [switch] $Check
+)
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference = 'Stop'
+
+$Root = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
+$Docs = Join-Path $Root 'src/docs'
+$Config = Join-Path $Root 'src/zensical.toml'
+$Start = ''
+$End = ''
+$Utf8 = [System.Text.UTF8Encoding]::new($false)
+
+function Read-FrontMatter {
+ param([string]$Path)
+ $meta = @{}
+ $text = [System.IO.File]::ReadAllText($Path)
+ if (-not $text.StartsWith('---')) { return $meta }
+ $closing = $text.IndexOf("`n---", 3)
+ if ($closing -lt 0) { return $meta }
+ foreach ($line in $text.Substring(3, $closing - 3) -split "`n") {
+ $stripped = $line.Trim()
+ if (-not $stripped -or $stripped.StartsWith('#') -or ($line -notmatch ':')) { continue }
+ $idx = $line.IndexOf(':')
+ $key = $line.Substring(0, $idx).Trim()
+ $value = $line.Substring($idx + 1).Trim().Trim('"').Trim("'")
+ if ($key -and $value) { $meta[$key] = $value }
+ }
+ return $meta
+}
+
+function Get-NavOrder {
+ $text = [System.IO.File]::ReadAllText($Config)
+ # Target the 'nav = [' key precisely (multiline, at the start of a line) so we
+ # never match other keys or values that merely contain 'nav', such as the
+ # 'navigation.*' theme features later in the file.
+ $match = [regex]::Match($text, '(?m)^\s*nav\s*=\s*\[')
+ if (-not $match.Success) {
+ throw "Could not find a 'nav = [' array in $Config."
+ }
+ $open = $match.Index + $match.Length - 1
+ $depth = 0
+ $end = -1
+ for ($p = $open; $p -lt $text.Length; $p++) {
+ if ($text[$p] -eq '[') { $depth++ }
+ elseif ($text[$p] -eq ']') { $depth--; if ($depth -eq 0) { $end = $p; break } }
+ }
+ if ($end -lt 0) {
+ throw "The 'nav' array in $Config is missing a closing ']'."
+ }
+ $navText = $text.Substring($open, $end - $open + 1)
+ $order = @{}
+ $i = 0
+ foreach ($m in [regex]::Matches($navText, '"([^"]+\.md)"')) {
+ $path = $m.Groups[1].Value
+ if (-not $order.ContainsKey($path)) { $order[$path] = $i; $i++ }
+ }
+ return $order
+}
+
+function Get-RelKey {
+ param([string]$FullPath)
+ return ($FullPath.Substring($Docs.Length).TrimStart('\', '/')) -replace '\\', '/'
+}
+
+function Get-IndexTable {
+ param([string]$IndexPath, [hashtable]$Order)
+ $dir = Split-Path -Parent $IndexPath
+ $subdirs = @(Get-ChildItem -LiteralPath $dir -Directory |
+ Where-Object { Test-Path (Join-Path $_.FullName 'index.md') } | Sort-Object Name)
+ $files = @(Get-ChildItem -LiteralPath $dir -File -Filter *.md |
+ Where-Object { $_.Name -ne 'index.md' } | Sort-Object Name)
+
+ $rows = [System.Collections.Generic.List[object]]::new()
+ foreach ($child in $subdirs) {
+ $target = Join-Path $child.FullName 'index.md'
+ $meta = Read-FrontMatter $target
+ $key = Get-RelKey $target
+ $rows.Add([pscustomobject]@{
+ Order = if ($Order.ContainsKey($key)) { $Order[$key] } else { 10000 }
+ Title = if ($meta.ContainsKey('title')) { $meta['title'] } else { $child.Name }
+ Link = "$($child.Name)/index.md"
+ Desc = if ($meta.ContainsKey('description')) { $meta['description'] } else { '' }
+ })
+ }
+ foreach ($child in $files) {
+ $meta = Read-FrontMatter $child.FullName
+ $key = Get-RelKey $child.FullName
+ $rows.Add([pscustomobject]@{
+ Order = if ($Order.ContainsKey($key)) { $Order[$key] } else { 10000 }
+ Title = if ($meta.ContainsKey('title')) { $meta['title'] } else { [System.IO.Path]::GetFileNameWithoutExtension($child.Name) }
+ Link = $child.Name
+ Desc = if ($meta.ContainsKey('description')) { $meta['description'] } else { '' }
+ })
+ }
+
+ $sorted = $rows | Sort-Object Order, { $_.Title.ToLower() }
+ $header = if ($subdirs.Count -and -not $files.Count) { 'Section' } else { 'Page' }
+ $lines = [System.Collections.Generic.List[string]]::new()
+ $lines.Add("| $header | Description |")
+ $lines.Add('| --- | --- |')
+ foreach ($r in $sorted) { $lines.Add("| [$($r.Title)]($($r.Link)) | $($r.Desc) |") }
+ return ($lines -join "`n")
+}
+
+function Get-Rendered {
+ param([string]$IndexPath, [hashtable]$Order)
+ $text = [System.IO.File]::ReadAllText($IndexPath)
+ if (($text -notlike "*$Start*") -or ($text -notlike "*$End*")) { return $null }
+ $head = $text.Substring(0, $text.IndexOf($Start) + $Start.Length)
+ $tail = $text.Substring($text.IndexOf($End))
+ return "$head`n`n$(Get-IndexTable $IndexPath $Order)`n`n$tail"
+}
+
+$order = Get-NavOrder
+$stale = [System.Collections.Generic.List[string]]::new()
+foreach ($index in (Get-ChildItem -LiteralPath $Docs -Recurse -File -Filter index.md | Sort-Object FullName)) {
+ $rendered = Get-Rendered $index.FullName $order
+ if ($null -eq $rendered) { continue }
+ if ($rendered -eq [System.IO.File]::ReadAllText($index.FullName)) { continue }
+ $stale.Add((($index.FullName.Substring($Root.Length).TrimStart('\', '/')) -replace '\\', '/'))
+ if (-not $Check) { [System.IO.File]::WriteAllText($index.FullName, $rendered, $Utf8) }
+}
+
+if ($stale.Count -eq 0) { exit 0 }
+if ($Check) {
+ Write-Output 'Documentation index tables are out of date:'
+ $stale | ForEach-Object { Write-Output " - $_" }
+ Write-Output 'Run: pwsh .github/scripts/Update-DocumentationIndex.ps1'
+ exit 1
+}
+Write-Output 'Updated index tables:'
+$stale | ForEach-Object { Write-Output " - $_" }
+exit 0
diff --git a/.github/scripts/Wait-CopilotReview.ps1 b/.github/scripts/Wait-CopilotReview.ps1
new file mode 100644
index 0000000..a428fc1
--- /dev/null
+++ b/.github/scripts/Wait-CopilotReview.ps1
@@ -0,0 +1,247 @@
+#Requires -Version 7.0
+
+<#
+ .SYNOPSIS
+ Request a Copilot review if needed, wait for it, and report whether Copilot left new comments.
+
+ .DESCRIPTION
+ Drives one round of the Copilot review loop from the
+ [Contribution Workflow](../../src/docs/Ways-of-Working/Contribution-Workflow.md).
+ It:
+
+ 1. Ensures a Copilot review is requested. It checks whether Copilot is
+ already processing a request (from the timeline - the org ruleset is not
+ relied upon, and reviewRequests empties almost immediately) and requests
+ one only if not (unless -SkipRequest).
+ 2. Polls until Copilot submits a review newer than the request, or the
+ timeout elapses.
+ 3. Reports the review state and any inline comments Copilot added this round,
+ and sets an exit code so a caller can branch on the result:
+
+ 0 clean round - Copilot requested no changes and left no new inline comments
+ 2 Copilot has feedback - a new inline comment or a changes-requested review
+ 1 no review arrived before the timeout
+
+ Requires the GitHub CLI (gh) authenticated for the target host.
+
+ .EXAMPLE
+ ./.github/scripts/Wait-CopilotReview.ps1 -Repository MSXOrg/docs -PullRequest 1
+
+ Requests a Copilot review on PR 1, waits for it, and reports the outcome.
+
+ .EXAMPLE
+ ./.github/scripts/Wait-CopilotReview.ps1 -Repository MSXOrg/docs -PullRequest 1 -SkipRequest
+
+ Waits for a review already requested elsewhere, without re-requesting one.
+
+ .INPUTS
+ None. This script does not accept pipeline input.
+
+ .OUTPUTS
+ [pscustomobject] with Repository, PullRequest, ReviewState, SubmittedAt,
+ NewCommentCount, NewComments, and Blessed.
+
+ .NOTES
+ Note the login asymmetry: the submitted review's author login is
+ 'copilot-pull-request-reviewer', while inline comments are attributed to
+ 'Copilot'.
+#>
+
+[OutputType([pscustomobject])]
+[CmdletBinding(SupportsShouldProcess)]
+param(
+ # Target repository in 'owner/name' form, e.g. 'MSXOrg/docs'.
+ [Parameter(Mandatory)]
+ [ValidatePattern('^[^/]+/[^/]+$')]
+ [string] $Repository,
+
+ # Pull request number.
+ [Parameter(Mandatory)]
+ [ValidateRange(1, [int]::MaxValue)]
+ [int] $PullRequest,
+
+ # GitHub host for gh; sets GH_HOST for the duration of the run.
+ [Parameter()]
+ [string] $GitHubHost = 'github.com',
+
+ # How long to wait for Copilot's review before giving up, in minutes.
+ [Parameter()]
+ [ValidateRange(1, 120)]
+ [int] $TimeoutMinutes = 10,
+
+ # Seconds between polls while waiting for the review.
+ [Parameter()]
+ [ValidateRange(5, 300)]
+ [int] $PollIntervalSeconds = 20,
+
+ # Poll for an already-requested review without requesting a new one.
+ [Parameter()]
+ [switch] $SkipRequest
+)
+
+$ErrorActionPreference = 'Stop'
+
+#region Constants
+# The reviewer bot's login on submitted reviews (inline comments show 'Copilot').
+Set-Variable -Name ReviewerLogin -Value 'copilot-pull-request-reviewer' -Option ReadOnly
+# The logins Copilot uses; the review bot posts inline comments as 'Copilot'.
+Set-Variable -Name CopilotLogins -Value @('Copilot', 'copilot-pull-request-reviewer') -Option ReadOnly
+# gh --jq filters, kept in variables so the gh calls stay within the line limit.
+Set-Variable -Name TimelineFilter -Option ReadOnly -Value @'
+.[] | select(.event=="review_requested" and (.requested_reviewer.login=="Copilot")) | .created_at
+'@
+Set-Variable -Name CommentFilter -Option ReadOnly -Value @'
+.[] | {path, line, body, login: .user.login, createdAt: .created_at}
+'@
+#endregion Constants
+
+# Preserve the caller's gh environment; $env: changes are process-wide, so
+# GH_HOST / GH_PAGER are restored on the way out.
+$previousGhHost = $env:GH_HOST
+$previousGhPager = $env:GH_PAGER
+
+try {
+ $env:GH_HOST = $GitHubHost
+ $env:GH_PAGER = ''
+
+ if ($SkipRequest) {
+ # Poll only - do not request. Look back over the whole timeout window so
+ # an already-submitted or in-flight review is still eligible.
+ Write-Verbose 'SkipRequest set - polling for an existing or in-flight Copilot review.'
+ $since = [datetimeoffset]::UtcNow.AddMinutes(-$TimeoutMinutes)
+ } else {
+ # Ensure a review is requested. Do NOT rely on any org ruleset to
+ # auto-request one. Copilot is 'processing' when there is a
+ # review_requested for it with no Copilot review since. Use the timeline,
+ # because reviewRequests empties almost immediately after the request.
+ $requestedAt = gh api "repos/$Repository/issues/$PullRequest/timeline" --paginate --jq $TimelineFilter
+ if ($LASTEXITCODE -ne 0) {
+ throw "Failed to read the timeline for $Repository#$PullRequest (gh exited $LASTEXITCODE)."
+ }
+ $lastRequestedAt = $requestedAt | Sort-Object | Select-Object -Last 1
+
+ $reviewsJson = gh pr view $PullRequest --repo $Repository --json reviews
+ if ($LASTEXITCODE -ne 0) {
+ throw "Failed to read reviews for $Repository#$PullRequest (gh exited $LASTEXITCODE)."
+ }
+ $lastReviewedAt = $reviewsJson | ConvertFrom-Json |
+ Select-Object -ExpandProperty reviews |
+ Where-Object { $_.author.login -eq $ReviewerLogin -and $_.submittedAt } |
+ ForEach-Object { [datetimeoffset] $_.submittedAt } |
+ Sort-Object |
+ Select-Object -Last 1
+
+ $processing = $lastRequestedAt -and
+ ((-not $lastReviewedAt) -or ([datetimeoffset] $lastRequestedAt -gt $lastReviewedAt))
+
+ if ($processing) {
+ Write-Verbose "Copilot is already processing a review (requested $lastRequestedAt) - waiting for it."
+ # Anchor just before the pending request so its review counts.
+ $since = ([datetimeoffset] $lastRequestedAt).AddSeconds(-1)
+ } elseif ($PSCmdlet.ShouldProcess("$Repository#$PullRequest", 'Request a Copilot review')) {
+ Write-Verbose "No Copilot review in progress - requesting one on $Repository#$PullRequest ..."
+ $null = gh pr edit $PullRequest --repo $Repository --add-reviewer '@copilot' 2>&1
+ if ($LASTEXITCODE -ne 0) {
+ throw "Failed to request a Copilot review (gh exited $LASTEXITCODE)."
+ }
+ Write-Verbose 'Requested a Copilot review.'
+ # Anchor after the request so only a review from this round counts.
+ $since = [datetimeoffset]::UtcNow
+ } else {
+ # -WhatIf: no request was made, so fall back to poll-only semantics
+ # (as with -SkipRequest) rather than waiting for a review that will
+ # never arrive. Look back over the window so an in-flight review counts.
+ Write-Verbose 'WhatIf - no review requested; polling for an existing or in-flight review.'
+ $since = [datetimeoffset]::UtcNow.AddMinutes(-$TimeoutMinutes)
+ }
+ }
+
+ $deadline = [datetimeoffset]::UtcNow.AddMinutes($TimeoutMinutes)
+ Write-Verbose "Waiting for a Copilot review (timeout ${TimeoutMinutes}m, every ${PollIntervalSeconds}s) ..."
+
+ $review = $null
+ while ([datetimeoffset]::UtcNow -lt $deadline) {
+ $reviewsJson = gh pr view $PullRequest --repo $Repository --json reviews
+ if ($LASTEXITCODE -ne 0) {
+ throw "Failed to read reviews for $Repository#$PullRequest (gh exited $LASTEXITCODE)."
+ }
+ $review = $reviewsJson | ConvertFrom-Json |
+ Select-Object -ExpandProperty reviews |
+ Where-Object {
+ $_.author.login -eq $ReviewerLogin -and
+ $_.submittedAt -and
+ [datetimeoffset] $_.submittedAt -gt $since
+ } |
+ Sort-Object { [datetimeoffset] $_.submittedAt } |
+ Select-Object -Last 1
+
+ if ($review) {
+ break
+ }
+
+ Start-Sleep -Seconds $PollIntervalSeconds
+ }
+
+ if (-not $review) {
+ Write-Warning "No Copilot review arrived within $TimeoutMinutes minute(s)."
+ exit 1
+ }
+
+ # Inline comments Copilot added in this round. Filter by author so human
+ # comments are not miscounted, and paginate so nothing is missed on a busy
+ # pull request.
+ $commentsJson = gh api "repos/$Repository/pulls/$PullRequest/comments" --paginate --jq $CommentFilter
+ if ($LASTEXITCODE -ne 0) {
+ throw "Failed to read review comments for $Repository#$PullRequest (gh exited $LASTEXITCODE)."
+ }
+ $newComments = @(
+ $commentsJson |
+ ForEach-Object { $_ | ConvertFrom-Json } |
+ Where-Object { $_.login -in $CopilotLogins -and [datetimeoffset] $_.createdAt -gt $since } |
+ ForEach-Object {
+ [pscustomobject]@{
+ Path = $_.path
+ Line = $_.line
+ Body = $_.body
+ }
+ }
+ )
+
+ # Blessed only when Copilot left no new inline comments AND did not request
+ # changes; a summary-only CHANGES_REQUESTED review has zero inline comments
+ # but is not a clean pass.
+ $blessed = $newComments.Count -eq 0 -and $review.state -ne 'CHANGES_REQUESTED'
+
+ if ($blessed) {
+ Write-Verbose 'Clean round - Copilot requested no changes and left no new inline comments.'
+ } else {
+ Write-Verbose "Copilot has feedback (state=$($review.state), new inline comments=$($newComments.Count))."
+ }
+
+ [pscustomobject]@{
+ Repository = $Repository
+ PullRequest = $PullRequest
+ ReviewState = $review.state
+ SubmittedAt = $review.submittedAt
+ NewCommentCount = $newComments.Count
+ NewComments = $newComments
+ Blessed = $blessed
+ }
+
+ if ($blessed) {
+ exit 0
+ } else {
+ exit 2
+ }
+} finally {
+ if ($null -eq $previousGhHost) {
+ Remove-Item -Path Env:\GH_HOST -ErrorAction SilentlyContinue
+ } else {
+ $env:GH_HOST = $previousGhHost
+ }
+ if ($null -eq $previousGhPager) {
+ Remove-Item -Path Env:\GH_PAGER -ErrorAction SilentlyContinue
+ } else {
+ $env:GH_PAGER = $previousGhPager
+ }
+}
diff --git a/.github/workflows/Docs.yml b/.github/workflows/Docs.yml
new file mode 100644
index 0000000..89ddf23
--- /dev/null
+++ b/.github/workflows/Docs.yml
@@ -0,0 +1,128 @@
+name: Docs
+
+on:
+ workflow_dispatch:
+ # No paths filter on purpose: this is the only workflow, so every push and pull
+ # request must run it to lint and build the full documented surface — including
+ # root files such as README.md, .github/dependabot.yml, and .prettierrc.json. A
+ # paths allow-list would silently skip CI for changes outside it.
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ # Cancel superseded PR runs for fast iteration, but let main-branch runs finish
+ # so a Pages deploy is never cancelled mid-publish.
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+# Default-deny floor for this multi-job workflow: each job below grants only the
+# scopes its steps need, so a job that omits its own permissions block (including
+# one added later) inherits nothing and fails closed. See the GitHub Actions
+# coding standard, "Grant least-privilege permissions".
+permissions: {}
+
+jobs:
+ lint:
+ name: Lint
+ runs-on: ubuntu-24.04
+ permissions:
+ contents: read
+ packages: read # super-linter: read packages
+ statuses: write # super-linter: report status checks
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ fetch-depth: 0
+ persist-credentials: false
+
+ - name: Lint code base
+ uses: super-linter/super-linter@9e863354e3ff62e0727d37183162c4a88873df41 # v8.6.0
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ # Vendored/minified third-party assets are not our code — don't lint them.
+ FILTER_REGEX_EXCLUDE: '.*\.min\.(js|css)$'
+ VALIDATE_BIOME_LINT: false
+ VALIDATE_BIOME_FORMAT: false
+ VALIDATE_JSCPD: false
+ VALIDATE_JSON_PRETTIER: false
+ VALIDATE_MARKDOWN_PRETTIER: false
+ VALIDATE_YAML_PRETTIER: false
+ VALIDATE_HTML_PRETTIER: false
+ # Python: lint with ruff, mypy, and isort; disable the formatters (version-coupled and mutually conflicting)
+ VALIDATE_PYTHON_BLACK: false
+ VALIDATE_PYTHON_FLAKE8: false
+ VALIDATE_PYTHON_PYLINT: false
+ VALIDATE_PYTHON_PYINK: false
+ VALIDATE_PYTHON_RUFF_FORMAT: false
+
+ build:
+ name: Build
+ runs-on: ubuntu-24.04
+ permissions:
+ contents: read
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ persist-credentials: false
+
+ - name: Set up Python
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ with:
+ python-version: 3.x
+
+ - name: Verify documentation indexes
+ shell: pwsh
+ run: ./.github/scripts/Update-DocumentationIndex.ps1 -Check
+
+ - name: Install Zensical
+ run: pip install -r requirements.txt
+
+ - name: Build Zensical project
+ run: zensical build --clean
+ working-directory: src
+
+ - name: Upload pages artifact
+ uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
+ with:
+ path: src/site
+
+ links:
+ name: Links
+ runs-on: ubuntu-24.04
+ permissions:
+ contents: read
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ persist-credentials: false
+
+ - name: Validate documentation links
+ shell: pwsh
+ run: ./.github/scripts/Test-DocumentationLink.ps1
+
+ publish:
+ name: Publish
+ needs: [build, lint, links]
+ if: github.event_name != 'pull_request'
+ runs-on: ubuntu-24.04
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ permissions:
+ contents: read
+ pages: write # deploy to GitHub Pages
+ id-token: write # OIDC token for actions/deploy-pages
+ steps:
+ - name: Configure pages
+ uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
+
+ - name: Deploy to GitHub Pages
+ uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
+ id: deployment
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..abd8c28
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+# Zensical build output
+src/site/
+
+# Python
+__pycache__/
+*.py[cod]
+.venv/
+venv/
+
+# OS / editor cruft
+.DS_Store
+Thumbs.db
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..5fcd8a7
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,3 @@
+{
+ "tabWidth": 4
+}
diff --git a/README.md b/README.md
index 8256cd5..0be7d8d 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,81 @@
-# docs
-The docs for everything MSX does on GitHub
+# MSX Docs
+
+The top-of-tree documentation for everything **MSX** builds on GitHub — the vision, principles, ways of working, and coding standards that every organization, repository, and agent in the ecosystem inherits.
+
+Published with [Zensical](https://zensical.org) to GitHub Pages: **[msxorg.github.io/docs](https://msxorg.github.io/docs/)**.
+
+## What's inside
+
+- **Vision** — the *why*: the mission and the philosophy of easy, fast, and safe.
+- **Initiatives** — the *what*: the products that make the vision real, from PSModule to reusable Actions and VS Code extensions.
+- **Ways of Working** — the *how*: workflow, principles, issue/PR/commit conventions, review etiquette, and more.
+- **Coding Standards** — language-agnostic standards for naming, layout, documentation, testing, and security.
+- **Capabilities** — the reusable specs and designs for what the ecosystem builds.
+- **Dictionary** — the shared vocabulary every reader and agent uses.
+
+The vision is written once, here, and referenced everywhere. Products change; the principles they express stay put.
+
+## Documentation conventions
+
+The docs are built for recursive navigation — a reader, or an agent, starts at the top index and drills down until it reaches the right page.
+
+- **Every page carries front matter.** Each `.md` file declares a `title` — the label used in navigation and the generated indexes — and a one-line `description`:
+
+ ```yaml
+ ---
+ title: Error Handling
+ description: Fail fast, never swallow, and write messages that help the next person.
+ ---
+ ```
+
+- **Every section has an index.** Each `index.md` holds an auto-generated table of the documents at its level, between markers:
+
+ ```markdown
+
+
+ ```
+
+- **The tables are generated from front matter.** `.github/scripts/Update-DocumentationIndex.ps1` reads each page's `title` and `description`, orders them to match the navigation in `src/zensical.toml`, and fills every index in place. Run it after adding or renaming a page:
+
+ ```pwsh
+ pwsh .github/scripts/Update-DocumentationIndex.ps1
+ ```
+
+ CI runs the same script with `-Check` and fails if an index is out of date.
+
+- **Links are validated.** `.github/scripts/Test-DocumentationLink.ps1` checks that every relative link and heading anchor across the docs resolves. It runs in CI on every pull request and on every push to `main`, alongside linting. Run it locally before opening a PR:
+
+ ```pwsh
+ pwsh .github/scripts/Test-DocumentationLink.ps1
+ ```
+
+The result is self-describing documentation: start at `src/docs/index.md`, read the descriptions, follow the link into a section, then into a page — repeating until you reach the document that fits the task.
+
+## Repository layout
+
+```text
+.github/
+ workflows/Docs.yml # lint, validate links, build, and publish to GitHub Pages
+ scripts/ # documentation tooling (index generation, link validation)
+ linters/ # shared linter configuration
+src/
+ zensical.toml # site configuration
+ docs/ # the documentation content
+ includes/ # shared snippets (abbreviations, links)
+ overrides/ # theme overrides
+```
+
+## Build locally
+
+The site is built with [Zensical](https://zensical.org), a Python static-site generator.
+
+```bash
+pip install -r requirements.txt
+cd src
+zensical serve # live preview at http://localhost:8000
+zensical build # output to src/site
+```
+
+## Contributing
+
+Every change lands through a pull request — nothing goes directly to `main`. Branch, build, open a draft PR, and let CI validate it. See the [Ways of Working](https://msxorg.github.io/docs/Ways-of-Working/) for the full workflow.
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..a7e396b
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,4 @@
+# Build toolchain for the documentation site.
+# Pinned to an exact version for reproducible CI builds; Dependabot proposes
+# updates deliberately (see .github/dependabot.yml).
+zensical==0.0.46
diff --git a/src/docs/Capabilities/dependency-updates/design.md b/src/docs/Capabilities/dependency-updates/design.md
new file mode 100644
index 0000000..a4a7544
--- /dev/null
+++ b/src/docs/Capabilities/dependency-updates/design.md
@@ -0,0 +1,108 @@
+---
+title: Design
+description: How dependency updates are built — Dependabot update PRs, a label scheme kept disjoint from release labels, and level-based auto-merge.
+---
+
+# Dependency Updates — Design
+
+The behaviour in the [spec](spec.md) is delivered by the platform-native updater
+([Dependabot](https://docs.github.com/code-security/dependabot)) configured in
+`.github/dependabot.yml`, plus a small labelling and auto-merge layer.
+
+## What gets checked
+
+| Kind | Trigger | Cadence |
+| --- | --- | --- |
+| **Version update** | A newer version of a pin exists | Scheduled (e.g. weekly), with a cooldown before a freshly published version is proposed |
+| **Security update** | A published advisory affects a pin | On disclosure, out of band from the schedule |
+
+## The updater
+
+Dependabot opens **one PR per outdated or vulnerable dependency** — or one per
+configured **group** of related dependencies — carrying the bump and the
+upstream release notes. SHA-pinned dependencies get the new commit SHA with the
+version as a trailing comment. Ecosystems, directories, schedule, cooldown,
+grouping, and the static labels all live in `.github/dependabot.yml`.
+
+```mermaid
+flowchart TD
+ check["Scheduled check / advisory"] --> pr["Open labelled update PR dependencies + ecosystem + update:LEVEL"]
+ pr --> ci["Required checks run (same gate as any PR)"]
+ ci --> route{"Update level"}
+ route -->|"patch / minor"| auto["Eligible for auto-merge"]
+ route -->|"major"| review["Human review required"]
+ auto --> merged["Merged"]
+ review --> merged
+ merged --> release["Artifact-affecting change → release"]
+```
+
+## Labels
+
+Every update PR carries **two independent dimensions**:
+
+| Label | Dimension | Meaning |
+| --- | --- | --- |
+| `dependencies` | category | Applied to **every** automated update PR. |
+| `github-actions` · `docker` · `terraform` · `npm` · `python` · `powershell` | ecosystem | Which ecosystem the update targets. One per PR. |
+| `update:major` | update level | The dependency crossed a **major** version — potentially breaking. |
+| `update:minor` | update level | The dependency gained a **minor** version — additive. |
+| `update:patch` | update level | The dependency took a **patch** — fix-level. |
+
+`dependencies` and the ecosystem label are applied statically by the updater
+config. The `update:*` label is derived from the update metadata
+(`version-update:semver-{major,minor,patch}`), so it is always accurate to the
+actual bump.
+
+### Separation from release versioning
+
+The `update:*` labels **must not** reuse the release-bump labels
+(`Major` / `Minor` / `Patch` / `NoRelease`). The two are different dimensions on
+the same pull request:
+
+| Dimension | Question | Label set | Owned by |
+| --- | --- | --- | --- |
+| **Release bump** | How much does *this repository's* version change? | `Major` · `Minor` · `Patch` · `NoRelease` | [Release Management](../release-management/spec.md) |
+| **Dependency update level** | How much did the *upstream dependency* change? | `update:major` · `update:minor` · `update:patch` | This capability |
+
+A dependency update is an **artifact-affecting change**, so merging it produces a
+release. If the PR carried a `Major` label to describe the *dependency's* jump,
+the release workflow would read it as a **major release of this repository** — a
+major upstream bump is very often only a patch, or no user-visible change, to the
+consuming artifact. So the two coexist: the **release bump** label (default
+`Patch`) governs this repository's version and is the label the release workflow
+reads; the **`update:*`** label is advisory metadata that drives review routing,
+never the bump.
+
+## Update-level policy
+
+| Update level | Handling |
+| --- | --- |
+| `update:patch`, `update:minor` | Eligible for **auto-merge** once all required checks pass. |
+| `update:major` | **Human review required**; never auto-merged. |
+
+Auto-merge is gated on green CI, never a bypass — every update passes the full
+check suite before it can merge. A repository may tighten this (require review
+for `update:minor` too) but never loosen it to auto-merge `update:major`.
+
+## Security updates
+
+Raised on advisory disclosure, independently of the schedule, and
+**prioritised**. They otherwise follow the same labels, the same review policy,
+and the same release path as any other update.
+
+## Configuration surface
+
+| Surface | Where |
+| --- | --- |
+| Ecosystems, directories, schedule, cooldown, grouping | `.github/dependabot.yml` |
+| Static labels (`dependencies` + ecosystem) | `.github/dependabot.yml` |
+| `update:*` labels | update metadata → labelling step |
+| Auto-merge policy | branch protection / auto-merge automation |
+| Security updates | repository security settings (on by default) |
+
+## Where this connects
+
+- [Spec](spec.md) — the requirements this design delivers.
+- [Release Management](../release-management/design.md) — the release an update PR cuts.
+- [Downstream Release Propagation](../downstream-release-propagation/design.md) — the internal counterpart; propagation PRs are dependency updates too.
+- [GitHub Actions](../../Coding-Standards/GitHub-Actions.md#keep-pinned-actions-current) — the Action-pin specifics this builds on.
diff --git a/src/docs/Capabilities/dependency-updates/index.md b/src/docs/Capabilities/dependency-updates/index.md
new file mode 100644
index 0000000..2ade1dc
--- /dev/null
+++ b/src/docs/Capabilities/dependency-updates/index.md
@@ -0,0 +1,20 @@
+---
+title: Dependency Updates
+description: How a repository's pinned dependencies are kept current and secure through automated, labelled update pull requests.
+---
+
+# Dependency Updates
+
+Keeping the pinned dependencies a repository consumes — Action and workflow
+SHAs, container base images, language packages, Terraform providers and
+modules — current and free of known vulnerabilities, through automated update
+pull requests that are reviewed and released like any other change.
+
+
+
+| Page | Description |
+| --- | --- |
+| [Spec](spec.md) | Requirements for dependency updates — pinned dependencies kept current and secure through reviewed, released update pull requests. |
+| [Design](design.md) | How dependency updates are built — Dependabot update PRs, a label scheme kept disjoint from release labels, and level-based auto-merge. |
+
+
diff --git a/src/docs/Capabilities/dependency-updates/spec.md b/src/docs/Capabilities/dependency-updates/spec.md
new file mode 100644
index 0000000..dc90cba
--- /dev/null
+++ b/src/docs/Capabilities/dependency-updates/spec.md
@@ -0,0 +1,52 @@
+---
+title: Spec
+description: Requirements for dependency updates — pinned dependencies kept current and secure through reviewed, released update pull requests.
+---
+
+# Dependency Updates — Spec
+
+## Premise
+
+Every repository pins dependencies by version — Action SHAs, image digests,
+package versions, provider constraints. Those pins age: a newer version fixes a
+bug the repository still carries, and a disclosed advisory turns a safe pin into
+a vulnerability. Keeping them current MUST be automatic and driven on the GitHub
+platform, producing ordinary pull requests that are reviewed and released
+through the same gate as any change — never a side channel that bypasses review.
+
+### Principles
+
+This capability rests on the [Principles](../../Ways-of-Working/Principles/index.md):
+
+- **[Everything as Code](../../Ways-of-Working/Principles/Engineering-Practices.md#everything-as-code).** What is checked and how often is version-controlled configuration, not a manual audit.
+- **[Decision before change](../../Ways-of-Working/Principles/AI-First-Development.md#decision-before-change).** Every update is a pull request; its review gate approves the bump and the release it produces.
+- **[Least-privilege](../../Ways-of-Working/Principles/Purpose-and-Direction.md#least-privilege).** The updater and any auto-merge automation carry only the permissions they need.
+- **[Extensible by default](../../Ways-of-Working/Principles/Software-Design.md#extensible-by-default).** Adding a package ecosystem is a configuration entry, not new machinery.
+
+## Scope
+
+Any repository that pins external dependencies: Action and workflow SHAs,
+container base images, language packages and lockfiles, Terraform providers and
+modules. Two questions are asked of every pin — **currency** (is a newer version
+available?) and **security** (does the pinned version carry a known advisory?).
+
+## Requirements
+
+- **Automatic checking.** Version currency is checked on a schedule; security advisories trigger updates out of band. No human watches upstream releases.
+- **One reviewed PR per update.** Each update is a pull request that passes the full CI gate before merge; nothing is applied unreviewed.
+- **Two labelled dimensions.** Every update PR is labelled with its category and ecosystem, and with the dependency's own version-change level.
+- **Labels MUST NOT collide with release versioning.** The label that signals the *dependency's* version level MUST NOT reuse the release-bump labels (`Major` / `Minor` / `Patch` / `NoRelease`). A dependency update is artifact-affecting and therefore *produces a release*; sharing one label set across the two dimensions would bump this repository's version off the wrong signal.
+- **SHA pins stay immutable.** An Action or workflow update rewrites the pin to the new commit SHA with the version as a trailing comment.
+- **Security first.** Security updates are prioritised over scheduled version updates.
+
+## Success criteria
+
+- An outdated or vulnerable pin produces a labelled pull request with no human trigger.
+- No dependency PR merges without passing the same checks as any other PR.
+- The dependency's version level is legible from labels without opening the diff, and never changes this repository's release bump by itself.
+
+## Where this connects
+
+- [Design](design.md) — the label scheme, the updater, and the auto-merge policy.
+- [Release Management](../release-management/spec.md) — the versioning update PRs feed into, and the bump labels these must not reuse.
+- [GitHub Actions](../../Coding-Standards/GitHub-Actions.md#keep-pinned-actions-current) — keeping pinned Actions current.
diff --git a/src/docs/Capabilities/downstream-release-propagation/design.md b/src/docs/Capabilities/downstream-release-propagation/design.md
new file mode 100644
index 0000000..6e8af4f
--- /dev/null
+++ b/src/docs/Capabilities/downstream-release-propagation/design.md
@@ -0,0 +1,109 @@
+---
+title: Design
+description: How downstream release propagation is built — an inline notification job that resolves the release and delegates a self-contained prompt to a cloud agent in each dependent.
+---
+
+# Downstream Release Propagation — Design
+
+The notification runs in the **producer** when a release is cut. It resolves the
+release coordinates, builds a self-contained prompt per dependent, and delegates
+the change to a cloud agent **in the dependent** via the
+[Agent Tasks API](https://docs.github.com/rest/agent-tasks/agent-tasks). The
+brief travels entirely in the prompt; the agent opens the pull request directly.
+
+```mermaid
+flowchart TD
+ rel["Producer release published"] --> notify["Notify job (in producer)"]
+ notify --> resolve["Resolve version + immutable ref (SHA / digest) + notes"]
+ resolve --> fan{"For each dependent"}
+ fan --> delegate["Create agent task in dependent self-contained prompt with full context"]
+ delegate --> pr["Agent opens PR: bump + related fixes + impact"]
+ pr --> review["Human review + merge"]
+```
+
+## Trigger model
+
+**The `GITHUB_TOKEN` constraint.** GitHub does not start new workflow runs from
+events raised by the default `GITHUB_TOKEN` (an anti-recursion safeguard). So if
+the producer publishes its release with `GITHUB_TOKEN` — the default — the
+`release: published` event never fires, and a separate `on: release` workflow
+never runs.
+
+| Release created by | `release: published` fires? | Trigger model |
+| --- | --- | --- |
+| `GITHUB_TOKEN` (default) | No | **Inline** — run notification in the same release run (`needs: `) or via `workflow_call`. |
+| A PAT | Yes | Either — a separate `on: release` workflow, or inline. |
+
+**Default to the inline model:** it works regardless of release identity and
+keeps the release and its propagation in one observable run. Verify the identity
+by which token the release step passes; if it is `GITHUB_TOKEN`, inline is
+mandatory. Provide two entry points: the **release** stage (gated to stable
+releases), and a **`workflow_dispatch`** taking the release tag, for backfill.
+
+## Release coordinate resolution
+
+| Coordinate | Meaning |
+| --- | --- |
+| `version` | Human-readable version — travels only as a tag / trailing comment |
+| immutable ref | The commit SHA (pinned-reference) or image digest (published-artifact) that dependents pin to |
+| `release_notes` | The producer's release body, embedded verbatim in the prompt |
+
+## Agent prompt context
+
+The prompt is the context handoff. Each embeds: an **action-oriented summary**;
+the **exact target reference** the PR must produce
+(`uses: org/@ # `, or the image tag/digest); the
+**release notes** verbatim; and
+**related-change context** — new or renamed config keys, new environment
+variables or secrets, required infrastructure changes, migrations, changed
+defaults, or breaking changes. It is assembled in code and is the single source
+of truth for the change.
+
+## Delegation
+
+The delegation step creates an agent task in the dependent carrying the prompt
+and the instruction to open the PR, then polls until the task reaches `queued`,
+`in_progress`, or `completed` (a fast task may go straight to `completed`). It
+**fails** only if the task cannot be created or lands in `failed`, `timed_out`,
+or `cancelled`. Fan-out is a **matrix** of dependents (pinned-reference shape) or
+a single configured `notify_repo` (published-artifact shape), with
+`fail-fast: false` so one dependent's failure does not stop the rest.
+
+## Agent instructions
+
+The agent is told to: **apply the bump** (every matching reference, bringing any
+mutable-tag pins into SHA-pinned compliance); **apply the related changes it can
+make safely**; **call out** larger or riskier work under a follow-up section
+rather than forcing it into the bump; **summarise impact** in the PR body; and
+**open the pull request**.
+
+## Permissions and credentials
+
+`GITHUB_TOKEN` is unsuitable for three independent reasons: it cannot act across
+repositories, it is not the user-to-server token the Agent Tasks API requires,
+and a release it publishes cannot trigger a `release:` workflow. So the job:
+
+- Declares **least-privilege** `permissions:` (`contents: read` suffices).
+- Uses `PROPAGATION_TOKEN` — a user PAT carrying the **Agent tasks** permission,
+ an org secret scoped to only the dependents that need it. Because the agent
+ commits and opens the PR within its task session, the token does not itself
+ push or open PRs.
+- Passes the secret **explicitly by name** when the notification is a reusable
+ workflow — never `secrets: inherit`, per the
+ [GitHub Actions coding standard](../../Coding-Standards/GitHub-Actions.md).
+
+## Failure behaviour
+
+| Condition | Behaviour |
+| --- | --- |
+| Task not created (missing permission / capability off) | Step **fails** with the error; re-run via `workflow_dispatch`. |
+| Task lands in a failed / timed-out / cancelled state | Step **fails** with the reported state. |
+| One dependent's leg fails | Fails independently (`fail-fast: false`); others proceed. |
+| Prerelease published | Propagation is skipped. |
+
+## Where this connects
+
+- [Spec](spec.md) — the requirements this design delivers.
+- [Release Management](../release-management/design.md) — produces the release and note this consumes.
+- [GitHub Actions](../../Coding-Standards/GitHub-Actions.md) — SHA pinning, least-privilege permissions, explicit secret passing.
+- [Security](../../Coding-Standards/Security.md#supply-chain) — the supply-chain rationale for immutable references.
diff --git a/src/docs/Capabilities/downstream-release-propagation/index.md b/src/docs/Capabilities/downstream-release-propagation/index.md
new file mode 100644
index 0000000..1a36d8e
--- /dev/null
+++ b/src/docs/Capabilities/downstream-release-propagation/index.md
@@ -0,0 +1,20 @@
+---
+title: Downstream Release Propagation
+description: How a release in one repository propagates to the repositories that depend on it, via a delegated agent pull request.
+---
+
+# Downstream Release Propagation
+
+When a producer cuts a release, every dependent automatically receives a pull
+request that applies the update — the version bump and the related changes it
+implies — opened by a delegated cloud agent, then reviewed and merged by a
+human. No dependent has to notice the release or track the bump by hand.
+
+
+
+| Page | Description |
+| --- | --- |
+| [Spec](spec.md) | Requirements for downstream release propagation — dependents automatically receive a reviewed pull request that applies each producer release. |
+| [Design](design.md) | How downstream release propagation is built — an inline notification job that resolves the release and delegates a self-contained prompt to a cloud agent in each dependent. |
+
+
diff --git a/src/docs/Capabilities/downstream-release-propagation/spec.md b/src/docs/Capabilities/downstream-release-propagation/spec.md
new file mode 100644
index 0000000..ca1d351
--- /dev/null
+++ b/src/docs/Capabilities/downstream-release-propagation/spec.md
@@ -0,0 +1,54 @@
+---
+title: Spec
+description: Requirements for downstream release propagation — dependents automatically receive a reviewed pull request that applies each producer release.
+---
+
+# Downstream Release Propagation — Spec
+
+## Premise
+
+The ecosystem is many small repositories that depend on each other by **version
+reference** — a pinned `uses:` SHA, an image digest, a deployed tag. A reference
+drifts the moment the producer cuts a release. Maintaining them by hand does not
+scale: missed bumps keep security fixes out of the workflows that run them, and
+missed *related* changes merge a bump that then breaks at runtime. When a
+producer releases, every dependent MUST automatically receive a pull request
+that applies the update — and the changes it implies — for a human to review.
+
+### Principles
+
+This capability rests on the [Principles](../../Ways-of-Working/Principles/index.md):
+
+- **[Everything as Code](../../Ways-of-Working/Principles/Engineering-Practices.md#everything-as-code).** Propagation is a workflow in the producer, not a checklist or a calendar reminder.
+- **[AI-first development](../../Ways-of-Working/Principles/AI-First-Development.md).** The automation creates context and delegates the change to an agent, which opens the PR; a human reviews and merges.
+- **[Least-privilege](../../Ways-of-Working/Principles/Purpose-and-Direction.md#least-privilege).** The notification uses a narrowly scoped cross-repo token, never a broad standing credential.
+- **[Written once, referenced everywhere](../../Ways-of-Working/Principles/Software-Design.md#dry-with-judgment).** Dependents are declared in one place in the producer; adding one is a one-line change.
+
+## Applicability
+
+Two shapes occur; both are the same mechanism with a different artifact:
+
+| Shape | Producer | Dependent | What the PR changes |
+| --- | --- | --- | --- |
+| **Pinned reference** | A reusable workflow or action | Repos that pin it with `uses:` | The pinned SHA, with the version as a trailing comment |
+| **Published artifact** | An app repo that builds a container image | The deploy repo that runs it | The deployed image tag / digest |
+
+## Requirements
+
+- **Automatic on stable release.** A stable producer release MUST trigger propagation to every declared dependent. Prereleases MUST NOT propagate.
+- **Full context, not just a number.** Each dependent receives the new version, the immutable reference (commit SHA or image digest), the release notes, and any related-change context the update implies.
+- **A PR per dependent, opened by an agent.** The mechanical work — the bump plus the fixes that make it work — is delegated to a cloud agent *in the dependent*, which opens the pull request directly. No tracking issue is created.
+- **Humans decide.** A human reviews and merges each PR; the agent applies what it can safely do now and calls out larger or riskier work as follow-up.
+- **Backfill on demand.** Propagation MUST be re-runnable for a specific release — for a missed event, or a dependent added after the release.
+
+## Success criteria
+
+- A stable release yields one PR in each declared dependent, carrying the immutable reference and an impact summary, with no manual tracking.
+- A prerelease yields none.
+- A dependent added after a release can be back-filled without cutting a new release.
+
+## Where this connects
+
+- [Design](design.md) — how these requirements are delivered.
+- [Release Management](../release-management/spec.md) — the release this propagates.
+- [Dependency Updates](../dependency-updates/spec.md) — the inbound counterpart, for external dependencies.
diff --git a/src/docs/Capabilities/index.md b/src/docs/Capabilities/index.md
new file mode 100644
index 0000000..735ab98
--- /dev/null
+++ b/src/docs/Capabilities/index.md
@@ -0,0 +1,28 @@
+---
+title: Capabilities
+description: The capabilities the ecosystem builds, each documented by a spec (why and what) and a design (how and what).
+---
+
+# Capabilities
+
+The independently versioned things the ecosystem builds and runs. Each
+capability is documented by a **spec** — the why and the what — and a
+**design** — the how and the what we build — kept side by side in the
+capability's folder. See the
+[Documentation Model](../Ways-of-Working/Documentation-Model.md) for how spec
+and design relate and evolve.
+
+
+
+| Section | Description |
+| --- | --- |
+| [Release Management](release-management/index.md) | How a source change becomes a versioned, immutable artifact, driven entirely on the GitHub platform. |
+| [Dependency Updates](dependency-updates/index.md) | How a repository's pinned dependencies are kept current and secure through automated, labelled update pull requests. |
+| [Downstream Release Propagation](downstream-release-propagation/index.md) | How a release in one repository propagates to the repositories that depend on it, via a delegated agent pull request. |
+
+
+
+## Where this connects
+
+- [Documentation Model](../Ways-of-Working/Documentation-Model.md) — the spec-and-design model every capability here follows.
+- [Ways of Working](../Ways-of-Working/index.md) — how the work that builds these capabilities happens.
diff --git a/src/docs/Capabilities/release-management/design.md b/src/docs/Capabilities/release-management/design.md
new file mode 100644
index 0000000..b24d5ee
--- /dev/null
+++ b/src/docs/Capabilities/release-management/design.md
@@ -0,0 +1,133 @@
+---
+title: Design
+description: How release management is built — a shared reusable workflow that reads pull-request labels, computes the SemVer bump, and cuts the release.
+---
+
+# Release Management — Design
+
+The behaviour in the [spec](spec.md) is delivered by a **shared reusable release
+workflow**. A repository opts in with a short caller workflow and a small
+`.github/release.config.yml`; everything else has a sensible default, so a
+minimal caller plus a one-line path filter is enough to adopt it.
+
+## Branching model
+
+A **release branch** is any branch configured as a release target, each with a
+**release type** — `stable` or `prerelease`.
+
+- **Single branch (zero-config).** One release branch (the default branch)
+ produces stable releases. Prereleases are opt-in via a PR label.
+- **Multi-branch.** `dev` (prerelease) collects PRs and publishes a prerelease
+ on every merge; `main` (stable) receives `dev`. Merging `dev → main` computes
+ the stable version from the **latest stable release** plus the merge PR's bump
+ label — the prerelease counter does not carry over.
+- **One production authority.** At most one branch is `release-type: stable`;
+ every other release branch is `prerelease`. The single stable branch
+ (typically `main`) owns the production version — a prerelease branch can never
+ cut a stable release.
+- **Bundled releases.** A **staging branch** collects feature PRs; merging it to
+ a release branch produces **exactly one** release for all bundled changes.
+
+```yaml
+# .github/release.config.yml
+release-branches:
+ - branch: main
+ release-type: stable
+ - branch: dev
+ release-type: prerelease
+```
+
+## Version computation
+
+- The bump comes from the PR label (`Major` / `Minor` / `Patch` / `NoRelease`),
+ defaulting to `Patch`. Multiple SemVer labels, or a SemVer label with
+ `NoRelease`, are **rejected**. For `workflow_dispatch`, the bump is an input.
+- **First release** starts from a baseline (`v0.1.0` or `v1.0.0`). Pre-`1.0.0`
+ breaking changes are `Minor` per [SemVer §4](https://semver.org/#spec-item-4);
+ `Major` is never auto-detected pre-`1.0.0`.
+- The tag is created on the commit now at the head of the release branch —
+ squash, merge-commit, and rebase strategies alike.
+
+## Prereleases
+
+- **Branch-level** — a prerelease-type branch publishes on every push, using the
+ branch name as the identifier: `v1.3.0-dev.1`, `v1.3.0-dev.2`, …
+- **PR-level** — a prerelease label on an open PR publishes
+ `v-.`: `base` is the next version from the PR's bump
+ label, `identifier` is the normalised branch name, and `counter`
+ auto-increments per push.
+- Artifact-specific conventions replace the SemVer suffix where they exist
+ (`-alpha.N` for npm, `.devN` for Python). Release candidates use `-rc.N`,
+ auto-incrementing.
+- **Cleanup** deletes prerelease tags, releases, and artifacts after the PR
+ closes (configurable); stable releases are never touched.
+
+## Path filtering
+
+`.github/release.config.yml` declares `release-paths` as ordered include/exclude
+globs (excludes win). The workflow **always runs** so validation executes on
+every merge; only the release step is skipped when no artifact-affecting path
+changed.
+
+```yaml
+release-paths:
+ - "src/**"
+ - "Dockerfile"
+ - "action.yml"
+ - "!docs/**" # documentation-only changes never release
+ - "!.github/**" # CI/CD changes never release
+```
+
+## Release notes
+
+The GitHub Release **name** is the version; the **body** depends on the trigger:
+`# ` + description (merged PR), `# ` + remainder
+(direct push), or `# ` + collected history (dispatch). The same note is
+handed to [Downstream Release Propagation](../downstream-release-propagation/design.md).
+
+## Release output
+
+1. A git tag `vX.Y.Z` on the release-branch commit — always.
+2. The published artifact where one lives outside git — a container image
+ (`:` and `@`), a package in its registry. For Action,
+ workflow, and module artifacts the tag itself **is** the artifact.
+3. A GitHub Release whose name is the version, carrying the note and the
+ immutable reference (digest, package version, or the tag).
+
+## Serialised releases
+
+Release runs for the same ref are **serialised** and **queue rather than
+cancel** — an in-flight release is never aborted mid-write, since it may be
+part-way through creating a tag or pushing an artifact. The shared workflow
+declares a concurrency group keyed by workflow and ref, with
+`cancel-in-progress` disabled:
+
+```yaml
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: false
+```
+
+Serialisation is provided once by the reusable workflow so every repository
+inherits it; the mechanism is the
+[GitHub Actions standard](../../Coding-Standards/GitHub-Actions.md#concurrency).
+The single-stable-branch rule above is what keeps the production version under
+one authority — the stable branch is the only ref that ever cuts a production
+release, and its runs are serialised like any other.
+
+## Configuration surface
+
+| Surface | Where |
+| --- | --- |
+| Release branches + type | `.github/release.config.yml` |
+| Bump label / prerelease / RC | PR label, or `workflow_dispatch` input |
+| Path filter | `.github/release.config.yml` |
+| Prerelease cleanup toggle | release config / workflow input |
+| Publish target | reusable-workflow input + GitHub environment |
+
+## Where this connects
+
+- [Spec](spec.md) — the requirements this design delivers.
+- [Downstream Release Propagation](../downstream-release-propagation/design.md) — consumes the release note and immutable reference.
+- [GitHub Actions](../../Coding-Standards/GitHub-Actions.md) — how the workflow itself is authored (SHA pins, least privilege, concurrency).
+- [Security](../../Coding-Standards/Security.md#supply-chain) — why consumers pin to immutable references.
diff --git a/src/docs/Capabilities/release-management/index.md b/src/docs/Capabilities/release-management/index.md
new file mode 100644
index 0000000..dd1f3d1
--- /dev/null
+++ b/src/docs/Capabilities/release-management/index.md
@@ -0,0 +1,21 @@
+---
+title: Release Management
+description: How a source change becomes a versioned, immutable artifact, driven entirely on the GitHub platform.
+---
+
+# Release Management
+
+Turning a merged change into a versioned, immutable artifact — a container
+image, a GitHub Action or reusable workflow, a language package, a Terraform
+module — paired with a GitHub Release and a git tag, driven entirely by
+pull-request labels. No release CLI, no hand-edited version file, no tagging
+ritual.
+
+
+
+| Page | Description |
+| --- | --- |
+| [Spec](spec.md) | Requirements for release management — automatic, label-driven, versioned releases driven entirely on the GitHub platform. |
+| [Design](design.md) | How release management is built — a shared reusable workflow that reads pull-request labels, computes the SemVer bump, and cuts the release. |
+
+
diff --git a/src/docs/Capabilities/release-management/spec.md b/src/docs/Capabilities/release-management/spec.md
new file mode 100644
index 0000000..87e0029
--- /dev/null
+++ b/src/docs/Capabilities/release-management/spec.md
@@ -0,0 +1,58 @@
+---
+title: Spec
+description: Requirements for release management — automatic, label-driven, versioned releases driven entirely on the GitHub platform.
+---
+
+# Release Management — Spec
+
+## Premise
+
+A release turns a source change on a release branch into a **versioned,
+immutable artifact** that other systems depend on. Merging a pull request *is*
+releasing. Releasing MUST be automatic, predictable, and driven entirely on the
+GitHub platform — a contributor focuses on the code they contribute, not a
+release CLI, a hand-edited version file, or a tagging convention.
+
+### Principles
+
+This capability rests on the [Principles](../../Ways-of-Working/Principles/index.md):
+
+- **[Everything as Code](../../Ways-of-Working/Principles/Engineering-Practices.md#everything-as-code).** The release process and version decision are version-controlled, never a GUI action or manual tag.
+- **[Decision before change](../../Ways-of-Working/Principles/AI-First-Development.md#decision-before-change).** The pull request is the decision point; its review gate approves the code *and* the release, and the bump label records the versioning decision explicitly.
+- **[Extensible by default](../../Ways-of-Working/Principles/Software-Design.md#extensible-by-default).** The rules are technology-agnostic at the core, with defined extension points per artifact type. A new artifact type supplies a convention and a publish step, not a new process.
+
+## Scope
+
+Applies to any repository that produces a versioned artifact on merge to a
+release branch. One test decides applicability: **does merging produce a
+versioned, immutable output that something else consumes by version?** If yes,
+this capability governs the release. If no, there is nothing to release.
+
+## Requirements
+
+- **Semantic versioning.** Versions follow [SemVer 2.0.0](https://semver.org/) (`vMAJOR.MINOR.PATCH`), derived automatically — never written by hand.
+- **Label-driven bump.** The bump level is a pull-request label — `Major` / `Minor` / `Patch` / `NoRelease` — defaulting to `Patch`. Conventional commit messages are **not** required.
+- **A release per merge.** One merged PR to a release branch is one release, and the PR review gate is the release gate. Direct pushes and manual dispatch also release.
+- **Stable and prerelease.** Every release is either **stable** (the latest version to adopt) or a **prerelease** (testable, not promoted to latest). A prerelease MUST be obtainable from an open pull request and/or from a prerelease branch.
+- **Serialised releases.** Only one release process runs against a given version of the codebase (the same ref) at a time. A release mutates shared, version-anchored state — the tag, the version counter, the published artifact — so overlapping runs on the same ref MUST NOT race, and an in-flight release is never interrupted.
+- **A single production authority.** Exactly one branch is in charge of the production (stable) version, so consumers get one unambiguous latest stable release and two branches can never publish competing production releases.
+- **Notes from the contributor's own words.** The GitHub Release name is the version; its body is assembled from material the contributor already wrote (PR title + description, or commit message, or collected history). The PR description is therefore written for consumers.
+- **Only artifact-affecting changes release.** A change that does not flow into the artifact (documentation, CI config) MUST NOT produce a release — though validation still runs on every merge.
+- **Immutable references.** Consumers pin to the most immutable reference available — a container digest or a commit SHA — never a mutable tag.
+- **Standard GitHub primitives only.** Pull requests, labels, comments, and workflow dispatch — no external tooling beyond `gh` and GitHub Actions.
+
+## Success criteria
+
+- Merging a labelled PR to a release branch produces a GitHub Release, a git tag, and (where one exists) a published artifact, with no manual step.
+- The version bump matches the PR's label every time; a conflicting or ambiguous label set is **rejected**, never guessed.
+- A documentation-only merge produces no new version but still runs its CI checks.
+- Two release runs for the same ref never overlap; the second waits for the first to finish rather than racing it.
+- Only the single production branch ever publishes a stable release.
+- Every release is linkable and records its immutable artifact reference.
+
+## Where this connects
+
+- [Design](design.md) — how these requirements are delivered.
+- [Documentation Model](../../Ways-of-Working/Documentation-Model.md) — why this spec holds only the why and the what.
+- [PR Format](../../Ways-of-Working/PR-Format.md) — the change-type labels that drive the bump.
+- [Dependency Updates](../dependency-updates/spec.md) — update PRs are artifact-affecting and release through this capability.
diff --git a/src/docs/Coding-Standards/Code-Layout.md b/src/docs/Coding-Standards/Code-Layout.md
new file mode 100644
index 0000000..30a0658
--- /dev/null
+++ b/src/docs/Coding-Standards/Code-Layout.md
@@ -0,0 +1,46 @@
+---
+title: Code Layout
+description: Structure, formatting, and file organization.
+---
+
+# Code Layout
+
+How code is structured on the page and across files. Layout is not cosmetic — consistent structure lets readers (and agents) navigate by shape, before they read a single word.
+
+## Formatting is automated
+
+The standard owns the formatting rules; the tooling enforces them automatically — in the editor, on commit, and in CI. A repository's formatter and linter configuration is **derived from these standards**, so the machine applies what is written here rather than defining it.
+
+- **Do not argue about formatting in review.** The standard has already decided; if the formatter accepts it, it matches the standard.
+- **Change a rule by changing the standard, not the config.** Adjust it here first, in its own PR; the derived tool config follows.
+- **The config lives in the repository**, in version control and traceable to this standard, so humans and agents apply the same rules.
+- This frees review attention for what actually matters: correctness, design, and clarity.
+
+See [Shift Left → pre-commit hooks](../Ways-of-Working/Principles/Engineering-Practices.md#pre-commit-hooks) for where these gates run.
+
+## Functions and units
+
+- **One responsibility per unit.** A function does one thing. If you need "and" to describe it, split it.
+- **Small enough to hold in your head.** A function that does not fit on a screen is usually doing too much. There is no hard line limit — fit is the test.
+- **Few parameters.** Many parameters signal a missing type or a function doing too much. Group related parameters into an object or split the function.
+- **Return early.** Guard clauses at the top beat deep nesting. Handle the edge cases and exits first, then the main path reads straight down.
+- **One level of abstraction per function.** Don't mix high-level orchestration with low-level byte-twiddling in the same body.
+
+## File and folder structure
+
+- **Predictable over clever.** A newcomer should guess where a thing lives. Mirror the language or framework's conventional layout rather than inventing one.
+- **Group by feature, then by type** when a codebase grows — co-locating the things that change together beats scattering them across type-named folders.
+- **One public thing per file** where the language encourages it (one exported function, class, or module per file). Easy to find, easy to diff, easy to move.
+- **Keep the root clean.** Configuration, source, tests, and docs each have a home. The repository root is a table of contents, not a junk drawer.
+
+## Within a file
+
+- **Order top-down.** Public surface first, private helpers below — read like a newspaper, headline before details.
+- **Imports and dependencies at the top**, grouped (standard library, third-party, local) and ordered consistently. Let the tooling sort them.
+- **Group related declarations.** Things used together live together.
+- **Whitespace is punctuation.** Blank lines separate ideas. A wall of code with no breaks is as hard to read as a paragraph with no sentences.
+
+## Comments and dead code
+
+- Delete dead code. Version control remembers it; the reader should not have to wonder whether the commented-out block matters.
+- A comment that restates the code is noise. A comment that explains *why* is gold. See [Documentation](Documentation.md).
diff --git a/src/docs/Coding-Standards/Documentation.md b/src/docs/Coding-Standards/Documentation.md
new file mode 100644
index 0000000..a1d8e9d
--- /dev/null
+++ b/src/docs/Coding-Standards/Documentation.md
@@ -0,0 +1,62 @@
+---
+title: Documentation
+description: Help that lives next to the code and explains the why.
+---
+
+# Documentation
+
+Documentation is part of the work, not a follow-up to it. Code that is not documented is effectively invisible — to the next contributor, to the user, and to the agents that read docs as their primary context.
+
+## The hierarchy of documentation
+
+Distance between a thing and its documentation is the rate at which they drift apart. Keep each kind of documentation as close to what it describes as possible:
+
+| Documentation | Lives |
+| -------------------- | ---------------------------------------------- |
+| Why a line exists | In a comment next to the line |
+| How a function works | In comment-based help next to the function |
+| What a repo is | In the README at the repository root |
+| How we work | In this org-level docs site |
+| Why a decision held | In the issue that produced it |
+
+## Self-documenting code first
+
+The best comment is the one you didn't need to write because the code said it already. Before adding a comment, ask whether a better name, a smaller function, or an extracted variable would remove the need. Reserve comments for what code *cannot* express.
+
+## Comment the why, not the what
+
+- **Bad:** `// increment i by one` — the code already says this.
+- **Good:** `// the API is 1-indexed, so the first page is 1 not 0` — context the code cannot carry.
+
+Comments explain intent, trade-offs, workarounds, and the reasons behind non-obvious choices. They are where you record *why this and not the obvious alternative*.
+
+## Keep comments concise
+
+Once a comment carries the why, it is done. A short phrase beats a paragraph, and a paragraph beats a screenful — over-explaining buries the one line that matters and rots as the code moves on.
+
+- **One line where one line works.** State the reason and stop. If the explanation keeps growing, it belongs in the design, an ADR, or the issue — link to it instead of inlining an essay.
+- **Don't narrate the code.** Skip step-by-step commentary, banner headers, and comments that just echo the next statement.
+- **Trust the reader.** Explain the non-obvious, not the ordinary — assume competence with the language and the codebase.
+
+- **Too expressive:** a five-line block walking through each step of a retry loop.
+- **Enough:** `// retry: the gateway 503s for a few seconds after a cold start`
+
+## Public surfaces are documented
+
+Every public function, command, module, or API carries documentation at its boundary — in the language's native format (comment-based help, docstrings, doc comments) so tooling can surface it. A consumer should never have to read the implementation to learn how to call it.
+
+Include, at minimum: what it does, its parameters, what it returns, and at least one example. Examples are worth a paragraph of prose each.
+
+## The README is the front door
+
+Every repository has a README that is the single source of truth for what the repository is and does. It is **evergreen** — updated in the same pull request that changes behavior, never as a separate task. A feature that ships without a README update is not done.
+
+See [README-Driven Context](../Ways-of-Working/Readme-Driven-Context.md) for the full model.
+
+## Write for someone with no context
+
+Assume the reader — human or agent — is seeing this for the first time. Use clear, direct language. Prefer an example over an explanation. Link to related material rather than restating it, so there is one source of truth and no drift.
+
+## Documentation is for agents too
+
+Agents read documentation as context before they act. A stale or missing doc does not just confuse a human — it makes an agent build the wrong thing. Keeping documentation ahead of code is what makes [context-first development](../Ways-of-Working/Principles/AI-First-Development.md#context-first-development) work at scale.
diff --git a/src/docs/Coding-Standards/Error-Handling.md b/src/docs/Coding-Standards/Error-Handling.md
new file mode 100644
index 0000000..66947b6
--- /dev/null
+++ b/src/docs/Coding-Standards/Error-Handling.md
@@ -0,0 +1,37 @@
+---
+title: Error Handling
+description: Fail fast, never swallow, and write messages that help the next person.
+---
+
+# Error Handling
+
+How code behaves when something goes wrong is part of its contract. Errors are surfaced, specific, and actionable — never swallowed.
+
+## Fail fast, fail loud
+
+- Validate inputs and preconditions early, and raise immediately when they are violated. The sooner a problem surfaces, the cheaper it is to fix.
+- A function that cannot fulfil its contract raises — it does not return a sentinel value that callers are free to ignore.
+
+## Never swallow errors
+
+- Don't catch an error only to discard it. An empty catch hides the failure and pushes the bug downstream, where it is far harder to diagnose.
+- Catch only what you can handle. If you cannot recover, let the error propagate to a layer that can — or to the top, where it is logged and surfaced.
+
+## Be specific
+
+- Catch specific, typed errors rather than a blanket catch-all. A broad catch silently hides failures you never anticipated.
+- Distinguish recoverable from fatal. Recoverable errors are handled in place; fatal ones stop the operation cleanly.
+
+## Messages serve the next person
+
+- An error message names what failed, the context it failed in, and — ideally — what to do about it. "Operation failed" helps no one; "cannot write to ``: permission denied" does.
+- Include enough context to diagnose without reproducing — identifiers, paths, and values. Never put secrets in a message or a log.
+
+## Separate the channels
+
+- Return values, diagnostics, warnings, and errors each travel on their own channel. Printing diagnostics where a caller expects data breaks composition and testing.
+- Respect the caller's verbosity and output preferences rather than forcing your own.
+
+## Clean up deterministically
+
+- Resources — files, handles, connections, locks — are released on every path, success or failure. Use the language's structured cleanup: `finally`, `defer`, context managers, disposables.
diff --git a/src/docs/Coding-Standards/Functions.md b/src/docs/Coding-Standards/Functions.md
new file mode 100644
index 0000000..374d2a7
--- /dev/null
+++ b/src/docs/Coding-Standards/Functions.md
@@ -0,0 +1,41 @@
+---
+title: Functions
+description: One responsibility, contracts in the signature, and validation at the boundary.
+---
+
+# Functions
+
+Functions are the unit of intent. A good function does one thing, says what it does through its name and signature, and can be understood without reading its body.
+
+## One responsibility
+
+- A function does one thing. If describing it needs the word "and", split it.
+- Keep it small enough to hold in your head. Whether it fits on a screen is a better test than a line count.
+- One level of abstraction per function — don't mix high-level orchestration with low-level detail in the same body.
+
+## Signatures are contracts
+
+- Type the parameters and return value where the language allows. The signature documents intent and lets tooling catch misuse before it runs.
+- Few parameters. A long parameter list signals a missing type or a function doing too much — group related arguments into an object.
+- Avoid boolean parameters that select behavior (`render(true)`). Split into two clearly named functions, or pass an explicit, named option.
+- Order parameters so the required ones come first — readers scan left to right.
+
+## Validate at the boundary
+
+- Reject bad input where it enters, before it travels deep into the call stack. A clear failure at the edge beats a baffling one three layers down. This is [shift left](../Ways-of-Working/Principles/Engineering-Practices.md#shift-left) applied to a single function.
+- Inside a validated boundary, trust the data. At the edge, trust nothing.
+
+## Flow reads top to bottom
+
+- Return early. Put guard clauses for edge cases and exits at the top, then let the main path read straight down — no deep nesting.
+- Prefer high-level constructs (iterate a collection directly) over manual, error-prone ones (index into it) when the index isn't needed.
+- Handle every case. A branch over a closed set of values covers every member or carries an explicit default — an unhandled value is a silent failure.
+
+## Side effects at the edges
+
+- Prefer pure functions: the output depends only on the input, with no hidden state and no side effects. Pure functions are trivial to test and to reason about.
+- Push side effects — I/O, mutation, network, time — to the edges of the system, and keep the core logic pure.
+
+## Gate destructive operations
+
+- Operations that create, change, or delete state offer a preview-or-confirm path before they act. Irreversible actions earn a deliberate gate. See [Security](Security.md).
diff --git a/src/docs/Coding-Standards/GitHub-Actions.md b/src/docs/Coding-Standards/GitHub-Actions.md
new file mode 100644
index 0000000..6352999
--- /dev/null
+++ b/src/docs/Coding-Standards/GitHub-Actions.md
@@ -0,0 +1,324 @@
+---
+title: GitHub Actions
+description: Workflow authoring — SHA pinning, least-privilege permissions, OIDC, secrets handling, and script extraction.
+---
+
+# GitHub Actions
+
+How GitHub Actions workflows are authored across the ecosystem. Workflows are
+code that runs with access to credentials and the ability to publish — they are
+held to the same bar as application code, plus the supply-chain and
+least-privilege controls below.
+
+This standard builds on the [language-agnostic baseline](index.md). For the
+threat model behind action pinning and vendoring, see
+[Security → Supply chain](Security.md#supply-chain); this standard is the
+canonical "how to author" reference that the security control points to.
+
+## Pin every action to a full commit SHA
+
+A `uses:` reference accepts a tag, a branch, or a commit SHA. Tags and branches
+are **mutable** — a maintainer (or an attacker who compromises one) can move
+them to point at different code. A full commit SHA is **immutable**.
+
+- **Pin every `uses:` to a full 40-character commit SHA.** Keep the human
+ version as a trailing comment so reviewers know the intended release.
+- This applies to **all** actions — third-party, first-party, and our own
+ internal actions alike.
+
+```yaml
+# Correct — immutable SHA; comment carries the readable version
+- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+
+# Avoid — mutable tag; the referenced code can change under us
+- uses: actions/checkout@v6
+```
+
+Internal actions follow the same rule.
+
+## Keep pinned actions current
+
+A SHA pin is immutable — which also means it does not move when the action
+publishes a fix. Pinning and updating are two halves of one practice: pin to a
+SHA for safety, then let automation propose the newer SHA so pins never rot into
+stale, unpatched code.
+
+- **Enable automated updates for the `github-actions` ecosystem** in
+ `.github/dependabot.yml`. The updater opens a pull request that rewrites the
+ pin to the new commit SHA and refreshes the trailing version comment.
+- **Apply a cooldown** before adopting a freshly published version, and
+ **group** low-risk action bumps so routine updates arrive as one reviewable
+ pull request rather than many.
+- **Label the update PR** with `dependencies` + `github-actions`, plus the
+ dependency's own level (`update:major` / `update:minor` / `update:patch`).
+ These update-level labels are deliberately **distinct from the release-bump
+ labels** (`Major` / `Minor` / `Patch`) — a bumped action is an
+ artifact-affecting change that itself cuts a release, so the two must not
+ share one label set.
+- **Review `update:major` by hand** — a major action bump can change inputs,
+ outputs, or behaviour. Lower levels may auto-merge once checks pass.
+
+The full mechanism — schedule, grouping, labels, and auto-merge policy — is the
+[Dependency Updates](../Capabilities/dependency-updates/design.md) capability;
+this section is the Actions-specific view of it.
+
+## Grant least-privilege permissions
+
+- **Set `permissions:` explicitly.** Never rely on the default token scope.
+- **Start from a default-deny floor.** In any workflow with more than one job,
+ declare `permissions: {}` at the workflow (top) level so the baseline is *no*
+ access, then grant each job only the scopes its steps need. A job that omits
+ its own `permissions:` block — including one added later — then inherits
+ nothing rather than the broad default token, so forgetting to scope a new job
+ fails *closed*, not open. (A single-job workflow may scope at the workflow
+ level, since the workflow and its one job are equivalent.)
+- **Declare permissions per job**, not only at workflow level, and grant only
+ the scopes that job needs. Most jobs need no more than `contents: read`.
+
+```yaml
+# Default-deny floor at the top; each job opts into exactly what it needs.
+permissions: {}
+
+jobs:
+ build:
+ runs-on: ubuntu-24.04
+ permissions:
+ contents: read # checkout only
+
+ deploy:
+ runs-on: ubuntu-24.04
+ permissions:
+ id-token: write # OIDC federation to the cloud provider
+ contents: read # checkout only
+```
+
+## Authenticate with OIDC, not long-lived secrets
+
+- **Use OIDC federation** (`id-token: write`) to obtain short-lived cloud
+ credentials — `azure/login` and the AWS role-assumption actions both support
+ it. Do not store long-lived cloud keys as secrets.
+- Scope the federated trust to the specific repository, ref, and environment.
+
+## Distinguish `vars` from `secrets`
+
+- **`secrets`** — anything whose disclosure is a security event (private keys,
+ API tokens). Never echo a secret to logs; never put one in `vars`.
+- **`vars`** — non-sensitive configuration (client IDs, account numbers,
+ gateway URLs). Using `vars` for config keeps secrets to the minimum that
+ truly needs protecting.
+- When calling a reusable workflow, **always pass secrets explicitly by name**
+ (`secrets: { TOKEN: ${{ secrets.TOKEN }} }`) so the dependency is visible at
+ the call site. **Never use `secrets: inherit`** — it silently forwards every
+ secret the caller holds and makes it impossible to tell from the call site
+ which secrets a workflow actually needs, defeating traceability and least
+ privilege. (Org variables are forwarded to reusable workflows automatically
+ and cannot be named — this rule is about `secrets`, not `vars`.)
+
+```yaml
+# Correct — only the needed secret is forwarded; the dependency is auditable
+jobs:
+ call:
+ uses: org/reusable-workflows/.github/workflows/build.yml@ # vX.Y.Z
+ secrets:
+ PROPAGATION_TOKEN: ${{ secrets.PROPAGATION_TOKEN }}
+
+# Avoid — forwards every secret; the call site no longer documents what's used
+jobs:
+ call:
+ uses: org/reusable-workflows/.github/workflows/build.yml@ # vX.Y.Z
+ secrets: inherit
+```
+
+## Never expand untrusted input inline
+
+Interpolating `${{ github.event.* }}` (PR titles, branch names, issue bodies)
+directly into a `run:` script allows shell injection. **Pass untrusted values
+through an `env:` variable** and reference the variable, which is not re-parsed
+as script.
+
+```yaml
+# Correct — value arrives as an environment variable, not inlined into the shell
+- env:
+ TITLE: ${{ github.event.pull_request.title }}
+ run: echo "$TITLE"
+
+# Avoid — attacker-controlled title is executed as shell
+- run: echo "${{ github.event.pull_request.title }}"
+```
+
+## Extract non-trivial `run:` scripts into an action
+
+A short `run:` step — a handful of commands wiring tools together — belongs
+inline. But once a step carries a **multi-line script embedded as a YAML
+string** (a block of Bash, Python, or PowerShell), that script is invisible to
+every linter, formatter, and editor: `shellcheck`, `ruff`, and the type
+checkers all see an opaque string, not code. Pull it out.
+
+- **A step whose logic is a non-trivial inline script must become its own
+ action.** The workflow then `uses:` that action instead of carrying the
+ script in its body. This keeps workflows declarative — what runs, in what
+ order, with what permissions — and moves the *how* into linted, testable
+ files.
+
+Extracting a script out of a workflow string is an instance of the
+[Code in code files](../Ways-of-Working/Principles/Engineering-Practices.md#code-in-code-files)
+principle: code earns linters, security scanning, and IDE support only once it
+lives in a file of its own language.
+
+### Generalize the action; drive behaviour through inputs and outputs
+
+An action that is lifted out of one workflow is tempting to write for exactly
+that workflow — hard-coding the repository, the branch, the message it posts.
+Resist this. An extracted action is a reusable unit, and it should be designed
+like one. The [SOLID](https://en.wikipedia.org/wiki/SOLID) principles map
+directly onto action design:
+
+- **Generalize to the work the action does, not the caller that needs it.**
+ Name and scope the action by its *capability* (`start-cloud-agent`,
+ `publish-docs`), not by the one situation that prompted it
+ (`bump-one-repo-pin`). The action does one well-defined job — a single
+ responsibility — and does it for any caller. This is what makes it reusable
+ rather than a copy of one workflow's internals.
+- **Adjust behaviour through the input interface, never by editing the action.**
+ Every value that varies between callers — the target repository, a model
+ name, a prompt, a flag — is an `input`, with a sensible `default` where one
+ exists. A new use case should be served by passing different inputs, not by
+ forking the script or adding a caller-specific branch inside it. The action is
+ *open for extension* (new inputs, new callers) but *closed for modification*
+ (its logic does not change to accommodate each new consumer).
+- **Keep defaults at the interface layer (`action.yml`) only.** Define optional
+ input defaults under `inputs..default` in `action.yml`, and treat that
+ as the single source of truth for caller-visible defaults. Do **not** duplicate
+ those defaults in runtime code (`main.js`, shell, Python, PowerShell). This
+ keeps the UI contract and auto-generated interface docs correct by construction,
+ and makes default changes one-line updates without drift.
+- **Keep the input interface focused.** Expose the inputs a caller genuinely
+ needs and no more; a narrow, well-named interface is easier to use correctly
+ than a broad one full of rarely-set knobs. Group related inputs rather than
+ leaking internal implementation details as parameters.
+- **Output anything a caller might reasonably act on.** Declare `outputs:` for
+ the results the action produces — an identifier it created, a URL, a computed
+ version, a pass/fail decision — so downstream steps consume a value instead of
+ re-deriving it or scraping logs. An action that does meaningful work and
+ returns nothing forces every caller to reconstruct what it already knew.
+
+```yaml
+# Correct — capability-named, behaviour driven by inputs, results surfaced
+inputs:
+ target-repository:
+ description: Repository the agent should work in (owner/repo).
+ required: true
+ agent:
+ description: Which cloud agent to start.
+ required: false
+ default: claude
+ prompt:
+ description: Full task description for the agent.
+ required: true
+outputs:
+ task-url:
+ description: URL of the created agent task, for callers to surface or poll.
+ # `start` is a step id under the action's own `runs.steps`.
+ value: ${{ steps.start.outputs.task-url }}
+
+# Avoid — hard-codes one caller's situation; nothing comes back out
+# no inputs: repo, agent, and prompt are baked into the script
+# no outputs: callers must scrape the log to find the task URL
+```
+
+Designing the action this way is the difference between *reuse* and
+*copy-paste*: a generalized action is consumed by SHA from many workflows; a
+caller-specific one gets duplicated and diverges the moment a second consumer
+appears.
+
+### Start local; promote when it is reused
+
+- **Default to a local action** under `.github/actions//`. That is
+ the right home for logic used by one repository.
+- **Promote to a standalone repository** only when the action is genuinely
+ reused across repositories. At that point it gains its own versioning and is
+ consumed by SHA like any other third-party action (see
+ [Pin every action to a full commit SHA](#pin-every-action-to-a-full-commit-sha)).
+ Do not reach for a separate repo preemptively — the cost of a shared release
+ surface is only worth paying once there is a second consumer.
+
+### Move the script into its own file
+
+- **Lift the script out of `action.yml` into a separate file** so tooling can
+ see it. The action's `run:` step then invokes that file rather than inlining
+ its contents. A script file is subject to its language's coding standard and
+ linter — for example the [PowerShell](PowerShell/index.md) standard — exactly as if
+ it lived in application code.
+- **One script file lives at the root of the action folder.** When the action
+ grows to several source files, **collect them under a `src/` folder** so the
+ action root stays readable.
+- **Name the entry script `main.`** (`main.py`, `main.sh`, `main.ps1`).
+ A consistent entry-point name makes the action's starting point unambiguous:
+ `main.` sits at the action root for a single-file action, or under `src/`
+ as the entry point alongside the other modules.
+
+## Toolchain
+
+Two linters enforce this standard in CI, and their configuration is derived from
+it — the rules above are the source of truth:
+
+- **[actionlint](https://github.com/rhysd/actionlint)** checks workflow
+ correctness: expression syntax, job and step wiring, runner labels, and the
+ shell of every `run:` step through shellcheck.
+- **[zizmor](https://docs.zizmor.sh/)** audits workflow security, flagging the
+ failures this standard exists to prevent: unpinned actions, excessive
+ `permissions`, template injection from untrusted input, `secrets: inherit`,
+ and persisted credentials.
+
+Both run through [super-linter](https://github.com/super-linter/super-linter) on
+every push and pull request, so a workflow that breaks this standard fails the
+build.
+
+```text
+# Single-file action — main. at the action root
+.github/actions/link-check/
+├── action.yml # uses: composite; the run step calls main.py
+├── main.py
+└── README.md
+
+# Multi-file action — sources under src/
+.github/actions/publish-docs/
+├── action.yml
+├── README.md
+└── src/
+ ├── main.py
+ ├── render.py
+ └── client.py
+```
+
+### Keep a README with the action
+
+- **Every action carries a `README.md`** describing what it does, its inputs and
+ outputs, and an example `uses:` snippet. This is the starting point a reader
+ hits first.
+- As an action grows — especially once it earns its own repository — fuller
+ reference material moves into a `docs/` folder there, and the README narrows
+ to an overview and a pointer into those docs. The README is always present;
+ it is the entry point, not the whole manual.
+
+## Concurrency
+
+Declare `concurrency` on workflows that must not race — anything that
+publishes, deploys, or mutates shared state. Use a stable group key and choose
+`cancel-in-progress` deliberately (`false` for publish/deploy so runs queue
+rather than abort mid-write).
+
+```yaml
+concurrency:
+ group: docs-publish
+ cancel-in-progress: false
+```
+
+## Pin the runner and name everything
+
+- **Pin `runs-on` to a specific runner image** (`ubuntu-24.04`) rather than
+ `ubuntu-latest`, so a runner upgrade is a deliberate, reviewable change rather
+ than a silent one.
+- **Give every job and every non-trivial step a `name:`.** Named steps make the
+ Actions UI and logs readable and make failures easy to locate.
diff --git a/src/docs/Coding-Standards/Markdown.md b/src/docs/Coding-Standards/Markdown.md
new file mode 100644
index 0000000..c3c313e
--- /dev/null
+++ b/src/docs/Coding-Standards/Markdown.md
@@ -0,0 +1,56 @@
+---
+title: Markdown
+description: GitHub Flavored Markdown authoring rules enforced by the shared markdownlint configuration.
+---
+
+# Markdown
+
+How Markdown is written across the ecosystem. All documentation is authored in [GitHub Flavored Markdown (GFM)](https://github.github.com/gfm/) and validated by a **single shared `markdownlint` configuration** that every repository consumes — no per-repo config drift.
+
+This standard covers the **syntax and style rules** the linter enforces. For how documentation lives next to the thing it describes, see the [Documentation](Documentation.md) baseline standard and [README-Driven Context](../Ways-of-Working/Readme-Driven-Context.md).
+
+## The shared configuration is the source of truth
+
+The rules below are enforced by `.github/linters/.markdown-lint.yml` (markdownlint via super-linter), run at PR time and again on the assembled artifact. The **same** config runs in both places, so a file that passes locally passes in CI. The configuration file — not this page — is authoritative if the two ever diverge.
+
+Check locally before opening a PR:
+
+```bash
+npx markdownlint-cli2 --config .github/linters/.markdown-lint.yml "src/docs/**/*.md"
+```
+
+## Enforced rules
+
+These overrides and defaults are active, so author to them:
+
+| Rule | Requirement |
+|---|---|
+| MD003 | Headings use **ATX** style (`# Heading`), never underline style. |
+| MD007 | Nested list items indent by **2 spaces**. |
+| MD025 | One H1 per document. A body `# Heading` is allowed **alongside** the YAML front-matter `title`. |
+| MD026 | Headings do not end with trailing punctuation (`. , ; : !`). |
+| MD046 | Code blocks are **fenced** (` ``` `), never indented. |
+| MD048 | Code fences use **backticks**, not tildes. |
+
+Beyond these the linter runs the default ruleset, so also honour its common defaults: headings tagged with a language on every code fence, no trailing whitespace, and a single trailing newline.
+
+## Relaxed on purpose
+
+These rules are disabled or widened so they do not flag valid documentation — do not work around them:
+
+- **MD004** (unordered list marker style) — disabled; a file may use any consistent bullet.
+- **MD013** (line length) — widened to 3000; prose and GFM tables wrap naturally.
+- **MD029** (ordered list prefix) — disabled; ordered lists may renumber freely.
+- **MD033** (inline HTML) — allowed, for Mermaid, ``, and layout constructs.
+- **MD036** (emphasis as heading) — allowed.
+- **MD041** (first line must be a heading) — disabled, to allow YAML front matter at the top of a file.
+- **MD060** (table column style) — disabled; compact and aligned GFM tables both pass.
+- **Blank-line rules** — disabled, so spacing around headings, lists, and fences is a matter of style rather than a lint error.
+
+## Style beyond the linter
+
+- **Write one H1, then never skip heading levels** — an H3 only appears under an H2.
+- **Use sentence-style headings.**
+- **Surround headings, lists, and fenced blocks with a blank line** for readability, even though the linter no longer enforces it.
+- **Prefer relative links** within a repository; use the canonical published URL for cross-repository references.
+- **Tag every code fence with a language** (` ```bash `, ` ```yaml `) so it is highlighted and converts cleanly when published.
diff --git a/src/docs/Coding-Standards/Naming.md b/src/docs/Coding-Standards/Naming.md
new file mode 100644
index 0000000..7f4131f
--- /dev/null
+++ b/src/docs/Coding-Standards/Naming.md
@@ -0,0 +1,46 @@
+---
+title: Naming
+description: Names that reveal intent, consistently, in every language.
+---
+
+# Naming
+
+Names are the primary interface to code. A good name removes the need for a comment; a bad name survives every refactor and misleads for years. Naming is the cheapest documentation we have — spend on it.
+
+## Principles
+
+- **Reveal intent.** A name should answer *what is this and why does it exist* without a comment. `daysUntilExpiry` beats `d`.
+- **Pronounceable and searchable.** If you cannot say it in a conversation or grep for it reliably, rename it. Avoid single letters except for trivial loop indices.
+- **No noise words.** `data`, `info`, `manager`, `helper`, `do`, `handle`, `process` carry no information. `userRecord` is not better than `user`; pick the one that is true.
+- **Consistency over cleverness.** One concept, one word, everywhere. Don't mix `fetch`, `get`, `retrieve`, and `load` for the same operation.
+- **Avoid abbreviations.** Spell it out. `configuration` over `cfg`, `repository` over `repo` — unless the abbreviation is more standard than the full form (`URL`, `ID`, `HTTP`).
+
+## By kind
+
+| Kind | Convention |
+| -------------------- | ------------------------------------------------------------------------- |
+| **Functions / methods** | A verb or verb phrase — they *do* something. `validateInput`, `Get-User`. |
+| **Variables / fields** | A noun or noun phrase — they *hold* something. `activeUsers`, `retryCount`. |
+| **Booleans** | A predicate that reads as true/false. `isReady`, `hasAccess`, `canRetry`. |
+| **Collections** | Plural. `users`, not `userList`. The type already says it is a list. |
+| **Constants** | Describe the value, not the magic number. `MAX_RETRIES`, not `FIVE`. |
+| **Types / classes** | A noun. `HttpClient`, `RetryPolicy`. |
+
+## Casing
+
+Follow the **idiom of the language**, and be consistent within a codebase:
+
+- Use the casing the language community expects — `PascalCase` for PowerShell functions and .NET types, `snake_case` for Python and Terraform, `camelCase` for JavaScript variables, `kebab-case` for CLI flags and filenames where idiomatic.
+- Never fight the language's conventions to impose a personal preference. The least-surprising name is the right name.
+- Files and folders follow the repository's established pattern. When starting fresh, prefer `kebab-case` for cross-platform safety (no case-sensitivity surprises between Windows, macOS, and Linux).
+
+## Scope and length
+
+Name length should track scope. A loop index living for three lines can be `i`. A module-level export read across the codebase earns a full, descriptive name. The wider the reach, the more the name has to carry on its own.
+
+## Anti-patterns
+
+- Encoding type into the name (`strName`, `arrUsers`) — the type system already knows.
+- Numbered suffixes (`user1`, `user2`, `dataNew`) — they signal a missing concept.
+- Negated booleans (`isNotReady`, `notReady`) — a negative name forces a double negative at every use, and a value turns it into a riddle: does `notReady = false` mean it *is* ready? Name the positive (`isReady`) and negate at the point of use.
+- Names that lie — a `getUser` that also writes to a cache is a name that lies. Rename or split.
diff --git a/src/docs/Coding-Standards/Performance.md b/src/docs/Coding-Standards/Performance.md
new file mode 100644
index 0000000..be9682e
--- /dev/null
+++ b/src/docs/Coding-Standards/Performance.md
@@ -0,0 +1,30 @@
+---
+title: Performance
+description: Scale with the input, measure before optimizing, clarity first.
+---
+
+# Performance
+
+Write code that scales with its input, measure before optimizing, and never trade clarity for speed you don't need.
+
+## Correct and clear first
+
+- Make it correct, make it clear, then make it fast — in that order. Most code is never the bottleneck.
+- Avoid premature optimization. Optimizing code that isn't hot adds complexity and buys nothing.
+
+## Know the cost
+
+- Be aware of algorithmic complexity. An O(n²) pattern in a loop — rebuilding a collection by copying it on every iteration — is fine for ten items and catastrophic for ten thousand.
+- Choose a data structure that matches the access pattern: a set for membership, a map for lookup, a list for ordered iteration.
+- Append to a growable structure; don't rebuild an immutable one on each pass.
+
+## Push work down and out
+
+- Filter as close to the source as possible. Let the database, API, or provider filter before the data crosses a boundary, rather than fetching everything and discarding most of it.
+- Stream large data sets instead of loading them entirely into memory.
+- Do work once. Hoist invariant computations out of loops, and cache results that are expensive to recompute and safe to reuse.
+
+## Measure, don't guess
+
+- Profile before optimizing. Intuition about bottlenecks is usually wrong — measure where the time actually goes.
+- Optimize the hot path, then confirm the gain with a measurement rather than a hunch.
diff --git a/src/docs/Coding-Standards/PowerShell/Classes.md b/src/docs/Coding-Standards/PowerShell/Classes.md
new file mode 100644
index 0000000..1df1b62
--- /dev/null
+++ b/src/docs/Coding-Standards/PowerShell/Classes.md
@@ -0,0 +1,44 @@
+---
+title: Classes
+description: When to reach for a PowerShell class, and how to structure its members, constructors, and documentation.
+---
+
+# Classes
+
+Prefer functions. Reach for a **class** only when you need a real type — structured data with behaviour, a custom enum, a DSC resource, or an argument-completer or validator class — not as a way to group operations. Grouping is what modules are for.
+
+## When to use a class
+
+- **Do** use a class for a strongly-typed data shape with methods, a custom validator or `[ArgumentCompleter]`, or an enum.
+- **Don't** use a class to namespace a set of operations — export functions from a module instead.
+
+## Section structure
+
+Lay a class out in a consistent order so members are easy to find:
+
+1. **Properties** — typed, `PascalCase`, with an inline comment where the intent is not obvious.
+2. **Constructors** — the default first, then more specific overloads.
+3. **Methods** — typed parameters and an explicit return type.
+
+```powershell
+class Repository {
+ # The owner/name slug, e.g. 'MSXOrg/docs'.
+ [string] $FullName
+
+ [bool] $Archived
+
+ Repository([string] $fullName) {
+ $this.FullName = $fullName
+ $this.Archived = $false
+ }
+
+ [string] ToString() {
+ return $this.FullName
+ }
+}
+```
+
+## Documentation
+
+- Document the class with a comment block above the `class` keyword, and each non-obvious property with an inline comment.
+- Keep classes in their own file (or a dedicated area of a module) and load them before the functions that depend on them.
diff --git a/src/docs/Coding-Standards/PowerShell/Functions.md b/src/docs/Coding-Standards/PowerShell/Functions.md
new file mode 100644
index 0000000..19b08a0
--- /dev/null
+++ b/src/docs/Coding-Standards/PowerShell/Functions.md
@@ -0,0 +1,73 @@
+---
+title: Functions
+description: Advanced functions — CmdletBinding, typed and validated parameters, pipeline blocks, ShouldProcess, and required comment-based help.
+---
+
+# Functions
+
+Functions are the primary unit of PowerShell. Write **advanced functions**, not basic ones — the advanced-function machinery gives callers `-Verbose`, `-ErrorAction`, `-WhatIf`, and discoverable help for free.
+
+## Section structure
+
+Every function body follows the same order, so any reader — or agent — knows where to look:
+
+1. **Comment-based help**, first, inside the body.
+2. **`[OutputType()]`** and **`[CmdletBinding()]`** (with `SupportsShouldProcess` when it mutates state).
+3. **`param()`** block — mandatory parameters first.
+4. **`begin` / `process` / `end`** blocks for pipeline functions; a single body otherwise.
+
+```powershell
+function Get-UserData {
+ <#
+ .SYNOPSIS
+ Get a user by id.
+
+ .DESCRIPTION
+ Return the user record for the given id.
+
+ .EXAMPLE
+ Get-UserData -UserId 'jdoe'
+ Returns the record for the user 'jdoe'.
+
+ .OUTPUTS
+ [PSCustomObject]
+ #>
+ [OutputType([PSCustomObject])]
+ [CmdletBinding()]
+ param(
+ # The unique identifier of the user.
+ [Parameter(Mandatory, Position = 0)]
+ [ValidateNotNullOrEmpty()]
+ [string] $UserId,
+
+ # Include deleted users in the result.
+ [Parameter()]
+ [switch] $IncludeDeleted
+ )
+
+ process {
+ # ...
+ }
+}
+```
+
+## Parameters
+
+- **Type every parameter** and validate at the boundary — `[Parameter(Mandatory)]`, `[ValidateSet(...)]`, `[ValidateNotNullOrEmpty()]` — so bad input is rejected early, not deep in the call stack.
+- **Attribute order**, each on its own line: `[Parameter()]`, then validation attributes, then `[ArgumentCompleter()]`, then `[Alias()]`, then the typed declaration.
+- **`[switch]` for boolean flags** — never a `[bool]` parameter.
+- **Name every parameter set** with an intent-revealing name when a function has more than one mode; never `Default` or `__AllParameterSets`. Set `DefaultParameterSetName` to the most common intent.
+
+## State changes and the pipeline
+
+- **Guard mutations with `ShouldProcess`.** A function that creates, changes, or deletes state declares `[CmdletBinding(SupportsShouldProcess)]` and wraps the change in `if ($PSCmdlet.ShouldProcess(...))`, so `-WhatIf` and `-Confirm` work. Never add `SupportsShouldProcess` to read-only verbs (`Get`, `Test`, `Resolve`).
+- **Design for the pipeline.** Functions that process collections accept `ValueFromPipeline` input and do the work in a `process` block, streaming output rather than buffering it.
+
+## Errors and output
+
+- **`throw` for terminating errors**; `Write-Error` only where the caller is expected to handle a non-terminating one.
+- **Emit one object type**, matching `[OutputType()]`; never `Write-Host` data another command might consume.
+
+## Comment-based help (required)
+
+Every public function carries comment-based help, first inside the body, with sections in this order: `.SYNOPSIS` (one imperative sentence), `.DESCRIPTION`, at least one `.EXAMPLE` per behaviour, then `.INPUTS`, `.OUTPUTS` (matching `[OutputType()]`), `.NOTES`, `.LINK`. Document each parameter with an inline comment above it rather than a `.PARAMETER` block, and let comments explain *why*, not *what*.
diff --git a/src/docs/Coding-Standards/PowerShell/Scripts.md b/src/docs/Coding-Standards/PowerShell/Scripts.md
new file mode 100644
index 0000000..ffcbe53
--- /dev/null
+++ b/src/docs/Coding-Standards/PowerShell/Scripts.md
@@ -0,0 +1,50 @@
+---
+title: Scripts
+description: Structure for standalone .ps1 scripts — requirements, parameters, help, and keeping the script thin.
+---
+
+# Scripts
+
+A script (`.ps1`) is an entry point, not a home for logic. Keep scripts **thin**: parse input, call functions, report results. Anything reusable belongs in a function in a module.
+
+## Section structure
+
+A script file is laid out top to bottom in this order:
+
+1. **`#Requires`** statements — PowerShell version and module dependencies with minimum versions.
+2. **Comment-based help** — `.SYNOPSIS`, `.DESCRIPTION`, and at least one `.EXAMPLE`.
+3. **`[CmdletBinding()]` + `param()`** — typed and validated, mandatory first; add `SupportsShouldProcess` when the script changes state.
+4. **`$ErrorActionPreference = 'Stop'`**.
+5. **Body** — the thin orchestration.
+
+```powershell
+#Requires -Version 7.0
+#Requires -Modules Pester
+
+<#
+ .SYNOPSIS
+ Rotate the automation secret and sync it to the target store.
+
+ .DESCRIPTION
+ Remove the current secret, create a replacement, and update the store that consumes it.
+
+ .EXAMPLE
+ ./Rotate-Secret.ps1 -ValidityDays 365
+#>
+[CmdletBinding(SupportsShouldProcess)]
+param(
+ # How long the new secret stays valid, in days.
+ [Parameter()]
+ [int] $ValidityDays = 180
+)
+
+$ErrorActionPreference = 'Stop'
+
+# thin orchestration: call the functions that do the real work
+```
+
+## Rules
+
+- **Name scripts `Verb-Noun.ps1`** to match the function convention.
+- **No side effects on load.** A script runs top to bottom when invoked; it should not do work merely by being dot-sourced.
+- **Return objects**, so the script composes in a pipeline like any other command.
diff --git a/src/docs/Coding-Standards/PowerShell/index.md b/src/docs/Coding-Standards/PowerShell/index.md
new file mode 100644
index 0000000..2dc4480
--- /dev/null
+++ b/src/docs/Coding-Standards/PowerShell/index.md
@@ -0,0 +1,59 @@
+---
+title: PowerShell
+description: Cross-platform PowerShell 7 — the conventions shared by every script, function, and class, with per-construct standards below.
+---
+
+# PowerShell
+
+How PowerShell is written across the ecosystem. PowerShell is the tool for operational automation — talking to platform APIs, orchestrating cross-platform tasks, and gluing tools together. We target **PowerShell 7 LTS** (the cross-platform `pwsh`) and lean on PowerShell's advanced-function machinery rather than plain scripts.
+
+This standard builds on the [language-agnostic baseline](../index.md); where the two overlap, the baseline rules apply and the conventions here add the PowerShell specifics. PowerShell is a heavily used language, so its standard **nests**: the shared conventions live on this page, and each construct — functions, classes, scripts — has its own page with the doc requirements, formatting, and section structure for that construct.
+
+
+
+| Page | Description |
+| --- | --- |
+| [Functions](Functions.md) | Advanced functions — CmdletBinding, typed and validated parameters, pipeline blocks, ShouldProcess, and required comment-based help. |
+| [Classes](Classes.md) | When to reach for a PowerShell class, and how to structure its members, constructors, and documentation. |
+| [Scripts](Scripts.md) | Structure for standalone .ps1 scripts — requirements, parameters, help, and keeping the script thin. |
+
+
+
+## Shared conventions
+
+These hold for all PowerShell, whatever the construct:
+
+- **`Verb-Noun` naming** with an approved verb (`Get-Verb`) and a singular noun: `Get-RepositorySecret`, not `Fetch-Secrets`.
+- **`PascalCase`** for functions, parameters, public variables, and class members; `camelCase` for local variables.
+- **Full cmdlet names, never aliases** (`Where-Object`, not `?`; `ForEach-Object`, not `%`).
+- **Set `$ErrorActionPreference = 'Stop'`** at the top of every script and module so errors are terminating, not silently swallowed.
+- **Emit objects, not formatted text.** Return rich objects and let the caller format; reserve `Write-Host` for genuine console UX, and use `Write-Verbose` / `Write-Information` for progress narration.
+
+## Formatting
+
+These rules define the layout; [PSScriptAnalyzer](#toolchain) enforces them (its settings are derived from this standard, not the reverse), so author to them and let the formatter apply them:
+
+- **One True Brace Style (OTBS).** Opening brace on the statement line, closing brace on its own line; always brace control blocks, even a single statement. No blank line straight after `{` or before `}`, and `else` / `elseif` / `catch` / `finally` sit on the line with the preceding closing brace.
+- **Indent with four spaces, never tabs**, and indent comment-based help to align with the function it documents.
+- **One space around operators and after commas** (`$a -eq $b`, `@(1, 2, 3)`), and **one space between a type and the name** — `[string] $Name`, not `[string]$Name`.
+- **`elseif` is one word**, not `else if`.
+- **Blank lines separate logical blocks.** No trailing whitespace, and end every file with a single newline.
+- **Keep code lines readable — aim for roughly 120 columns.** When a call grows long, prefer [splatting](#idioms-and-pitfalls) over backtick line-continuations.
+
+## Idioms and pitfalls
+
+Beyond the basics, these language-specific habits keep PowerShell correct and fast:
+
+- **Single-quote strings unless you need expansion.** Use `'literal'` by default; reserve `"...$var..."` for interpolation or escape sequences, and here-strings (`@'...'@`, `@"..."@`) for multi-line text — literal-versus-interpolated intent then stays obvious.
+- **Splat calls that carry many parameters.** Build a `@{}` of parameters and splat it (`Get-Thing @params`) instead of a long line of `-Param value` pairs or backtick continuations; it reads better and diffs cleanly.
+- **Put `$null` on the left of a comparison** — `$null -eq $x`, never `$x -eq $null`. Against a collection the right-hand form *filters* rather than tests. Use `-contains` / `-in` for membership, never `-eq`.
+- **Suppress unwanted output with `$null = ...`** (or `[void]` for method calls), not `| Out-Null` — the pipeline form is markedly slower on hot paths.
+- **Build collections with a typed list, not `+=` in a loop.** `$a += $x` reallocates the whole array every iteration; use `[System.Collections.Generic.List[T]]` with `.Add()`, and prefer a cmdlet's `-Filter` over piping to `Where-Object` on large sets.
+- **Keep secrets out of source, and never `Invoke-Expression` untrusted input.** Take secrets as `[securestring]` or through `Get-Credential`, and guard state-changing commands with `ShouldProcess` (see [Functions](Functions.md)); the wider rules live in the [Security](../Security.md) baseline.
+
+## Toolchain
+
+The toolchain enforces this standard in CI — it does not define it. The rules above are the source of truth; each tool's configuration is derived from them:
+
+- **[PSScriptAnalyzer](https://github.com/PowerShell/PSScriptAnalyzer)** is the linter and formatter; its settings are derived from this standard, so passing it cleanly means matching the standard. Let it format — do not hand-format.
+- **[Pester](https://pester.dev/)** is the test framework; test files are named `*.Tests.ps1`. See the [Testing baseline](../Testing.md).
diff --git a/src/docs/Coding-Standards/Security.md b/src/docs/Coding-Standards/Security.md
new file mode 100644
index 0000000..4d9a72d
--- /dev/null
+++ b/src/docs/Coding-Standards/Security.md
@@ -0,0 +1,51 @@
+---
+title: Security
+description: Least privilege, secret hygiene, and the OWASP baseline.
+---
+
+# Security
+
+Security is a property of how we build, not a phase at the end. The cheapest vulnerability to fix is the one caught in the editor; the most expensive is the one found in production. Shift it left.
+
+## Least privilege, everywhere
+
+Every identity — human, agent, or workflow — gets only the permissions it needs for its specific task, and nothing more.
+
+- Workflow jobs declare `permissions` explicitly and as narrowly as possible. A job that only reads never has write access.
+- Tokens and API scopes are minimal and scoped to the step or job that uses them — never passed wider.
+- Agents are scoped to the actions they are authorized to take. An agent that reviews code cannot merge it.
+- Expanding a scope is a deliberate, reviewed decision — never a default or a shortcut.
+
+The goal is to limit blast radius: if any one identity is compromised, the damage is contained. See [Principles → Least-privilege](../Ways-of-Working/Principles/Purpose-and-Direction.md#least-privilege).
+
+## Secrets stay secret
+
+- **Never commit secrets.** No tokens, keys, passwords, or connection strings in source — not even briefly, not even in history.
+- **Secret scanning runs on every commit and PR.** A pre-commit hook and a CI gate catch leaks before they spread.
+- **Secrets live in a vault** or the platform's secret store, injected at runtime, never baked into images or config.
+- **Prefer short-lived, federated credentials.** Where a platform supports it, authenticate with OIDC or workload-identity federation instead of storing a long-lived secret. A token that lasts minutes and is scoped to one job beats a key that sits in a vault for a year.
+- **Rotate on exposure.** A leaked secret is a compromised secret — revoke and rotate, don't hope.
+
+## Validate at the boundaries
+
+Validate and sanitize all input where it crosses a trust boundary — user input, API responses, file contents, environment variables, anything from outside the system. Inside a validated boundary, trust the data; at the edge, trust nothing.
+
+Be especially deliberate where untrusted input meets a powerful sink: shell commands, SQL, templating, deserialization, and dynamic code. These are where the [OWASP Top 10](https://owasp.org/www-project-top-ten/) lives.
+
+## The OWASP baseline
+
+All code is written to be free of the vulnerabilities in the [OWASP Top 10](https://owasp.org/www-project-top-ten/) — injection, broken access control, insecure deserialization, and the rest. Treat them as a checklist for any code that touches a trust boundary, and fix insecure patterns the moment they are spotted rather than filing them for later.
+
+## Supply chain
+
+Our dependencies are part of our attack surface.
+
+- **Pin dependencies** to a known-good version. Pin GitHub Actions to a full commit SHA, not a moving tag.
+- **Automate updates** with a dependency bot, so patches land quickly and reviewably.
+- **Make builds reproducible.** Lock or vendor dependencies so a build resolves the same inputs every time — and can run without network access where that matters.
+- **Generate provenance.** Build artifacts carry a software bill of materials (SBOM) and build attestations, so what is inside a release is verifiable.
+- **Minimize the surface.** Every dependency is a liability as well as a convenience — add them deliberately, remove them when unused.
+
+## Secure by default
+
+The secure choice should be the easy choice and the default choice. Design tools and templates so that doing the right thing requires no extra effort, and a deliberate override is required to do the risky thing — never the reverse. This is [Easy](../index.md) and [Safe](../index.md) applied to security.
diff --git a/src/docs/Coding-Standards/Terraform.md b/src/docs/Coding-Standards/Terraform.md
new file mode 100644
index 0000000..93d65a6
--- /dev/null
+++ b/src/docs/Coding-Standards/Terraform.md
@@ -0,0 +1,64 @@
+---
+title: Terraform
+description: Stack layout, version pinning, state and secrets, and the fmt/validate/tflint toolchain.
+---
+
+# Terraform
+
+How Terraform is written across the ecosystem. Terraform is the tool for provisioning cloud infrastructure as code. Infrastructure changes go through the same review and approval gates as application code — see [Decision before change](../Ways-of-Working/Principles/AI-First-Development.md#decision-before-change).
+
+This standard builds on the [language-agnostic baseline](index.md); where the two overlap, the baseline rules apply and the conventions below add the Terraform specifics.
+
+## Stack layout
+
+Split a stack into conventional files so a reader knows where to look:
+
+| File | Holds |
+|---|---|
+| `providers.tf` | `terraform` block, `required_version`, `required_providers`, backend, `provider` blocks. |
+| `variables.tf` | Input variable declarations. |
+| `locals.tf` | Local values and computed names. |
+| `data.tf` | Data sources. |
+| `main.tf` | The resources themselves. |
+| `outputs.tf` | Output values. |
+
+Name resources, variables, and outputs in `lower_snake_case`, and name a resource for its role — not its type (`aws_s3_bucket.docs_artifact`, not `aws_s3_bucket.bucket`).
+
+## Pin versions and lock them
+
+- **Constrain `required_version`** for Terraform itself and **constrain every provider** with a pessimistic operator (`version = "~> 5.0"`).
+- **Commit the `.terraform.lock.hcl` dependency lockfile.** The constraint bounds the range; the lockfile fixes the exact resolved versions so every apply and every engineer uses the same providers.
+
+```hcl
+terraform {
+ required_version = ">= 1.5"
+
+ backend "s3" {}
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.0"
+ }
+ }
+}
+```
+
+## State and secrets
+
+- **Use a remote backend** (such as S3) for shared state — never local state for anything shared or deployed. Configure the backend partially in code and supply the rest at `init`.
+- **Never put secrets in `.tf` files or in variables' defaults.** State can contain sensitive values, so treat the state backend as sensitive and mark sensitive outputs `sensitive = true`.
+- **Apply default tags** at the provider level (`default_tags`) so every resource is consistently labelled.
+
+## Variables and outputs
+
+- **Type every variable** and give it a `description`; add `validation` blocks where inputs have real constraints.
+- Only set a `default` for genuinely optional inputs; required inputs have no default so a missing value fails fast.
+- **Describe every output**, and expose only what other stacks or operators actually consume.
+
+## Tooling
+
+- **`terraform fmt`** — canonical formatting; CI runs `terraform fmt -check`.
+- **`terraform validate`** — configuration is valid before plan.
+- **[`tflint`](https://github.com/terraform-linters/tflint)** — catches provider-specific issues and anti-patterns.
+- Review the **`terraform plan`** output before every apply; an apply is never a surprise.
diff --git a/src/docs/Coding-Standards/Testing.md b/src/docs/Coding-Standards/Testing.md
new file mode 100644
index 0000000..34bad5f
--- /dev/null
+++ b/src/docs/Coding-Standards/Testing.md
@@ -0,0 +1,52 @@
+---
+title: Testing
+description: The executable specification — test-first, locally runnable, deterministic.
+---
+
+# Testing
+
+Tests are the executable specification. They define the behavior we want, prove we built it, and catch the day it breaks. They are written as part of the work — not bolted on afterward.
+
+## Test-first
+
+Define the test when you define the behavior. Writing the test first forces you to design the interface from the caller's side, and it gives you an unambiguous definition of done: the test passes.
+
+For logic with branches, edge cases, or anything involving money, time, or security — red-green-refactor is the default. For trivial glue code, judgment applies; dogma does not.
+
+See [Test-Driven Development](../Ways-of-Working/Principles/Engineering-Practices.md#test-driven-development).
+
+## Testable locally
+
+A developer or an agent must be able to run the full suite **on their own machine** — no cloud resources, no special access, no secrets that cannot be mocked. If you cannot test it locally, you cannot reason about it in your editor, and the cost of every change goes up.
+
+This is a design constraint, not a nicety. When building anything new, ask early: *can someone run this locally?* If the answer is no, the design is wrong.
+
+## The test pyramid
+
+Most tests should be fast and narrow; few should be slow and broad.
+
+- **Unit** — the foundation. Fast, isolated, no I/O. The bulk of the suite.
+- **Integration** — components together, real boundaries. Fewer, slower, higher-value.
+- **End-to-end** — the whole system. Fewest of all; reserved for critical paths.
+
+Inverting the pyramid — leaning on slow, brittle end-to-end tests — produces a suite that is painful to run and quick to be ignored.
+
+## Properties of a good test
+
+- **Deterministic.** Same input, same result, every time. A test that passes intermittently is worse than no test — it trains people to ignore failures. No reliance on wall-clock time, network, ordering, or shared mutable state.
+- **Isolated.** Each test sets up and tears down its own world. Tests do not depend on each other or on run order.
+- **Fast.** The inner loop is where engineering time is spent; slow tests get skipped.
+- **Readable.** A test is also documentation. Arrange–act–assert, one behavior per test, a name that states the expectation.
+- **One reason to fail.** When a test breaks, its name and body should make the cause obvious.
+
+## Coverage with judgment
+
+Coverage is a signal, not a goal. High coverage of trivial code while the hard branches go untested is a false comfort. Aim coverage at the code that carries risk — logic, edge cases, error handling — and don't chase a percentage for its own sake.
+
+## When a bug escapes
+
+A bug that reached production is a missing test. The fix is incomplete until a test reproduces the failure and then passes — so the same regression can never return silently. Fixing the source without closing the test gap leaves the next regression just as invisible.
+
+## Tests run in CI
+
+Every pull request runs the suite before a human review begins. Validation that depends on a reviewer remembering to check is validation that eventually fails. Automate it once; it protects every PR after. See [Shift Left](../Ways-of-Working/Principles/Engineering-Practices.md#shift-left).
diff --git a/src/docs/Coding-Standards/TypeScript.md b/src/docs/Coding-Standards/TypeScript.md
new file mode 100644
index 0000000..2714e2a
--- /dev/null
+++ b/src/docs/Coding-Standards/TypeScript.md
@@ -0,0 +1,46 @@
+---
+title: TypeScript
+description: ES modules, strict-mode typing, pinned dependencies, and the Prettier/ESLint/Vitest toolchain for Node tooling and VS Code extensions.
+---
+
+# TypeScript
+
+How TypeScript is written across the ecosystem. TypeScript is the language for Node-based tooling, GitHub Actions written in JavaScript, and **VS Code extensions**. We target the **latest stable TypeScript** on the **Node.js Active LTS**, ship **ES modules**, and treat the compiler's strict mode as non-negotiable.
+
+This standard builds on the [language-agnostic baseline](index.md); where the two overlap, the baseline rules apply and the conventions below add the TypeScript specifics.
+
+## Project shape
+
+- **ES modules** — set `"type": "module"` in `package.json` and use `import`/`export`, not CommonJS `require`.
+- **Pin the Node.js version** with an `engines.node` field so the runtime is explicit.
+- Source lives under `src/`; compiled output is generated, never committed.
+- Author in **TypeScript, not plain JavaScript**, for anything beyond a trivial single-file script. Small build helpers may be `.mjs`.
+
+## Dependencies are pinned
+
+- **Pin dependencies to exact versions** in `package.json` — no `^` or `~` ranges. The lockfile plus exact versions makes every install reproducible.
+- Keep runtime `dependencies` and `devDependencies` correctly separated.
+
+## Compiler strictness
+
+- **`"strict": true`** in `tsconfig.json`, and keep it on — strict mode is the main reason to use TypeScript at all.
+- **Typecheck in CI** with `tsc --noEmit` as a dedicated step, separate from the build.
+- Avoid `any`; reach for `unknown` and narrow, or define the type. An `// @ts-expect-error` or `any` escape hatch must carry a comment justifying it.
+- Model absence explicitly (`T | null` / `T | undefined`) and handle it; do not lean on implicit `undefined`.
+
+## Naming and declarations
+
+- **`camelCase`** for variables and functions, **`PascalCase`** for types and classes, **`UPPER_SNAKE_CASE`** for constants.
+- Prefer `const`; use `let` only when reassignment is real; never `var`.
+
+## Style and tooling
+
+The toolchain is the enforcement mechanism — formatting and linting are not matters of taste, and both run in CI.
+
+- **[Prettier](https://prettier.io/)** owns formatting (`prettier --check` in CI); do not hand-format.
+- **[ESLint](https://eslint.org/)** with the TypeScript plugin is the linter; code must pass `eslint` cleanly.
+
+## Testing
+
+- **[Vitest](https://vitest.dev/)** is the test runner; colocate or mirror tests and run them in CI (`vitest run`, with coverage on the CI path).
+- Tests are the executable specification — see the [Testing baseline](Testing.md).
diff --git a/src/docs/Coding-Standards/index.md b/src/docs/Coding-Standards/index.md
new file mode 100644
index 0000000..434fdf7
--- /dev/null
+++ b/src/docs/Coding-Standards/index.md
@@ -0,0 +1,50 @@
+---
+title: Coding Standards
+description: The shared baseline every repository inherits, and the per-language standards that build on it.
+---
+
+# Coding Standards
+
+Standards for code written anywhere in the MSX ecosystem, in two tiers. The **baseline** encodes the [Principles](../Ways-of-Working/Principles/index.md) at the level of day-to-day code — how it is named, laid out, documented, tested, and secured — and applies in every language. The **per-language standards** add the idioms of one language or tool on top, and never contradict the baseline.
+
+These standards are prescriptive, and they are the source of truth: the relevant linter or formatter is the enforcement mechanism, and its configuration is derived from the standard — never the other way around. Wherever a rule can be checked mechanically, a linter derived from the standard enforces it in CI.
+
+## Contents
+
+The baseline pages apply to all code and come first; the per-language standards build on them and follow.
+
+
+
+| Page | Description |
+| --- | --- |
+| [Naming](Naming.md) | Names that reveal intent, consistently, in every language. |
+| [Code Layout](Code-Layout.md) | Structure, formatting, and file organization. |
+| [Functions](Functions.md) | One responsibility, contracts in the signature, and validation at the boundary. |
+| [Error Handling](Error-Handling.md) | Fail fast, never swallow, and write messages that help the next person. |
+| [Documentation](Documentation.md) | Help that lives next to the code and explains the why. |
+| [Testing](Testing.md) | The executable specification — test-first, locally runnable, deterministic. |
+| [Performance](Performance.md) | Scale with the input, measure before optimizing, clarity first. |
+| [Security](Security.md) | Least privilege, secret hygiene, and the OWASP baseline. |
+| [GitHub Actions](GitHub-Actions.md) | Workflow authoring — SHA pinning, least-privilege permissions, OIDC, secrets handling, and script extraction. |
+| [Markdown](Markdown.md) | GitHub Flavored Markdown authoring rules enforced by the shared markdownlint configuration. |
+| [PowerShell](PowerShell/index.md) | Cross-platform PowerShell 7 — the conventions shared by every script, function, and class, with per-construct standards below. |
+| [Terraform](Terraform.md) | Stack layout, version pinning, state and secrets, and the fmt/validate/tflint toolchain. |
+| [TypeScript](TypeScript.md) | ES modules, strict-mode typing, pinned dependencies, and the Prettier/ESLint/Vitest toolchain for Node tooling and VS Code extensions. |
+
+
+
+## Two tiers
+
+The **baseline** applies in every language — naming, code layout, functions, error handling, documentation, testing, performance, and security. Every repository inherits it.
+
+The **per-language standards** capture the idioms of one language or tool: the conventions, the toolchain that enforces them, and the rationale where it is not obvious. A PowerShell module, a Terraform stack, a GitHub Actions workflow, and a Markdown document each have idioms of their own. A per-language standard always builds on the baseline and never contradicts it — where they overlap, the baseline rule applies and the per-language page adds the specifics.
+
+## The one rule above the rules
+
+> Code is read far more often than it is written.
+
+Every standard here serves that single fact. When a rule and readability disagree, readability wins — and the rule gets revisited. When in doubt, optimize for the next person (or agent) who has to understand the code cold.
+
+## How standards evolve
+
+Standards are evergreen, not frozen. When one stops serving us, we change it — in a pull request, against this repository, with the reasoning written down. A standard that cannot be justified is a standard that should be removed.
diff --git a/src/docs/Dictionary/index.md b/src/docs/Dictionary/index.md
new file mode 100644
index 0000000..fd45066
--- /dev/null
+++ b/src/docs/Dictionary/index.md
@@ -0,0 +1,94 @@
+---
+title: Dictionary
+description: Shared vocabulary for the MSX ecosystem — the terms a reader or agent meets across these docs.
+---
+
+# Dictionary
+
+Shared vocabulary for the MSX ecosystem: the terms that appear across this site, defined once so every reader — human or agent — reads them the same way. Ecosystem-specific terms link to the page that covers them in full.
+
+## Terms
+
+### Agent
+
+An AI participant that reads the same documentation as a human and acts on the platform — opening issues, proposing pull requests, and reviewing changes. See [Agentic Development](../Ways-of-Working/Agentic-Development.md).
+
+### Baseline
+
+The language-agnostic tier of the [Coding Standards](../Coding-Standards/index.md) — naming, layout, functions, testing, and security — that every repository inherits regardless of language.
+
+### Capability
+
+An independently versioned thing the ecosystem builds and runs, documented by a spec and a design. See [Capabilities](../Capabilities/index.md).
+
+### CI/CD
+
+Continuous integration and continuous delivery — automated build, test, and release triggered on every change, so quality is checked before a change lands.
+
+### Coding Standard
+
+A prescriptive rule set for how code is written, per language or technology, enforced by a linter derived from it. See [Coding Standards](../Coding-Standards/index.md).
+
+### Continuous X
+
+The family of always-on practices — continuous integration, delivery, documentation, and AI — that keep work flowing in small increments. See [Continuous Practices](../Ways-of-Working/Continuous-Practices.md).
+
+### Design
+
+The *how* of a capability: the approach and the thing built, kept beside its spec. See the [Documentation Model](../Ways-of-Working/Documentation-Model.md).
+
+### Directive
+
+Guidance written to be declarative and directional — it states what must be true and the direction to move, and leaves the *how* to the doer. Standards, principles, and specs are written as directives.
+
+### Initiative
+
+A product that makes the vision real — a framework, a set of reusable actions, or an editor extension. See [Initiatives](../Initiatives/index.md).
+
+### Least privilege
+
+Every identity — human, agent, or workflow — gets only the permissions it needs, and nothing more. See [Principles → Least-privilege](../Ways-of-Working/Principles/Purpose-and-Direction.md#least-privilege).
+
+### LTS
+
+Long-Term Support — a release line maintained with fixes for an extended period. We target current LTS runtimes rather than legacy editions.
+
+### Philosophy
+
+The most stable tier of belief — *why* we exist and what we value: easy, fast, safe. It informs the [Principles](../Ways-of-Working/Principles/index.md).
+
+### Practice
+
+How we habitually act on a principle — concrete and evolving, such as pinning actions to a commit SHA. See [Principles](../Ways-of-Working/Principles/index.md).
+
+### Principle
+
+Something that is always true for us — rarely changing, sitting between philosophy and practice. See [Principles](../Ways-of-Working/Principles/index.md).
+
+### Pull request
+
+The unit of change and the decision point: proposed changes are reviewed, validated by CI, and approved before they merge. See [PR Format](../Ways-of-Working/PR-Format.md).
+
+### SemVer
+
+Semantic Versioning — a `MAJOR.MINOR.PATCH` scheme where the number communicates the kind of change a release contains.
+
+### Shift Left
+
+Move quality gates as early as possible — editor, pre-commit, and pull request — because the later a problem is caught, the more it costs. See [Principles → Shift Left](../Ways-of-Working/Principles/Engineering-Practices.md#shift-left).
+
+### Spec
+
+The *why* and *what* of a capability: the contract it fulfils, kept beside its design. See the [Documentation Model](../Ways-of-Working/Documentation-Model.md).
+
+### Vision
+
+The *why* of the whole ecosystem — make software delivery easy, fast, and safe. See the [Vision](../Vision/index.md).
+
+### Ways of Working
+
+The shared conventions for how work happens — workflow, issues, reviews, and the norms every contributor and agent follows. See [Ways of Working](../Ways-of-Working/index.md).
+
+### Zensical
+
+The static-site generator that builds this documentation from Markdown and publishes it to GitHub Pages.
diff --git a/src/docs/Initiatives/AzActions.md b/src/docs/Initiatives/AzActions.md
new file mode 100644
index 0000000..8a619a4
--- /dev/null
+++ b/src/docs/Initiatives/AzActions.md
@@ -0,0 +1,10 @@
+---
+title: AzActions
+description: Reusable building blocks for automating Azure on GitHub.
+---
+
+# AzActions
+
+**[AzActions](https://github.com/AzActions)** is where the principles meet the cloud: reusable GitHub Actions and workflows that make automating **Azure** consistent, observable, and safe.
+
+It applies the same [Coding Standards](../Coding-Standards/index.md) and [Ways of Working](../Ways-of-Working/index.md) as everything else in the ecosystem — the vision, applied to infrastructure automation.
diff --git a/src/docs/Initiatives/PSModule.md b/src/docs/Initiatives/PSModule.md
new file mode 100644
index 0000000..c81530d
--- /dev/null
+++ b/src/docs/Initiatives/PSModule.md
@@ -0,0 +1,15 @@
+---
+title: PSModule
+description: The GitHub + PowerShell framework — reusable modules and the actions that ship them.
+---
+
+# PSModule
+
+**[PSModule](https://github.com/PSModule)** makes it *easy* to build, test, and ship PowerShell on GitHub — the fullest expression of the vision, end-to-end.
+
+It is two things at once:
+
+- **A module-building workflow** — GitHub Actions and reusable workflows that automate the whole PowerShell delivery lifecycle: build, test, version, and publish.
+- **The modules themselves** — a growing collection of reusable PowerShell modules built with that workflow.
+
+PSModule inherits the [Coding Standards](../Coding-Standards/index.md) and [Ways of Working](../Ways-of-Working/index.md) from this site and adds only what is specific to the framework. Its own documentation lives at [psmodule.io](https://psmodule.io).
diff --git a/src/docs/Initiatives/TFActions.md b/src/docs/Initiatives/TFActions.md
new file mode 100644
index 0000000..b092084
--- /dev/null
+++ b/src/docs/Initiatives/TFActions.md
@@ -0,0 +1,10 @@
+---
+title: TFActions
+description: Reusable building blocks for automating Terraform and infrastructure as code.
+---
+
+# TFActions
+
+**[TFActions](https://github.com/TFActions)** brings the vision to infrastructure as code: reusable GitHub Actions and workflows that make automating **Terraform** consistent, observable, and safe.
+
+Infrastructure changes flow through the same review and approval gates as application code — see [Decision before change](../Ways-of-Working/Principles/AI-First-Development.md#decision-before-change) — and follow the same [Coding Standards](../Coding-Standards/index.md) and [Ways of Working](../Ways-of-Working/index.md).
diff --git a/src/docs/Initiatives/VS-Code-Extensions.md b/src/docs/Initiatives/VS-Code-Extensions.md
new file mode 100644
index 0000000..a45df44
--- /dev/null
+++ b/src/docs/Initiatives/VS-Code-Extensions.md
@@ -0,0 +1,10 @@
+---
+title: VS Code Extensions
+description: Editor tooling that brings the MSX way of working into VS Code.
+---
+
+# VS Code Extensions
+
+Editor tooling that brings the MSX way of working directly into **VS Code** — meeting developers where they already are, so the *easy* path and the *right* path are the same one.
+
+These extensions are authored in [TypeScript](../Coding-Standards/TypeScript.md) and inherit the [Coding Standards](../Coding-Standards/index.md) and [Ways of Working](../Ways-of-Working/index.md) from this site.
diff --git a/src/docs/Initiatives/index.md b/src/docs/Initiatives/index.md
new file mode 100644
index 0000000..542436c
--- /dev/null
+++ b/src/docs/Initiatives/index.md
@@ -0,0 +1,40 @@
+---
+title: Initiatives
+description: The products that make the vision real — PSModule, AzActions, TFActions, and the tools built along the way.
+---
+
+# Initiatives
+
+The **initiatives** are where the vision becomes something you can use. Each one is a product — a framework, a set of reusable actions, an editor extension — that answers a single question:
+
+> What would this look like if it were *easy*, to move *fast*, in a *safe* way?
+
+The vision, principles, ways of working, and coding standards are written once, here, and **inherited** by every initiative. Products grow, change, and occasionally retire; the principles they express stay put.
+
+
+
+| Page | Description |
+| --- | --- |
+| [PSModule](PSModule.md) | The GitHub + PowerShell framework — reusable modules and the actions that ship them. |
+| [AzActions](AzActions.md) | Reusable building blocks for automating Azure on GitHub. |
+| [TFActions](TFActions.md) | Reusable building blocks for automating Terraform and infrastructure as code. |
+| [VS Code Extensions](VS-Code-Extensions.md) | Editor tooling that brings the MSX way of working into VS Code. |
+
+
+
+## How they fit together
+
+```mermaid
+flowchart TD
+ V["MSX — vision, ways of working, coding standards (this site)"]
+ V --> PS["PSModule GitHub + PowerShell framework"]
+ V --> AZ["AzActions Azure automation"]
+ V --> TF["TFActions Terraform automation"]
+ V --> EXT["VS Code Extensions the way of working, in the editor"]
+```
+
+Each initiative inherits the principles on this site rather than restating them — read the vision once, see it applied many times. New ideas are incubated in **[MSXOrg](https://github.com/MSXOrg)** — tooling, infrastructure, and experiments — before they earn a place of their own.
+
+## A living map
+
+This list grows and changes as the work does. What stays constant is the relationship: every initiative points back to the [Vision](../Vision/index.md). When you want to know *why* something is built the way it is, the answer is here; when you want to see *what* that looks like in practice, open an initiative.
diff --git a/src/docs/Vision/index.md b/src/docs/Vision/index.md
new file mode 100644
index 0000000..f798d57
--- /dev/null
+++ b/src/docs/Vision/index.md
@@ -0,0 +1,70 @@
+---
+title: Vision
+description: The mission and the philosophy of easy, fast, and safe.
+---
+
+# Vision
+
+MSX exists to make great software delivery the **default** — easy, fast, and safe — for every developer and every agent.
+
+This page is the **why**. It is the most stable thing on this site: products, languages, and tools change, but the reason they exist does not. Everything else — the [Ways of Working](../Ways-of-Working/index.md), the [Coding Standards](../Coding-Standards/index.md), and the [Initiatives](../Initiatives/index.md) — flows from here.
+
+## Start with Why
+
+Work at every level is grounded in three concentric questions — the [Golden Circle](../Ways-of-Working/Principles/Purpose-and-Direction.md#start-with-why-the-golden-circle):
+
+- **Why** — what change in the world are we trying to make? *Make the right thing the easy thing, so good software ships fast and safely.*
+- **How** — what approach makes that change happen? *Everything as code, context before code, deterministic automation first, AI where judgment is needed, humans in the loop.*
+- **What** — what concrete thing are we delivering right now? *The frameworks, actions, modules, and tools in the [Initiatives](../Initiatives/index.md).*
+
+The Why is constant. The How is the way of working. The What is replaceable.
+
+## The mission
+
+> Make great software delivery the default — easy, fast, and safe — for every developer and every agent.
+
+A mission is something anyone can read and immediately have ideas about how to contribute. It is not a roadmap and it is not a product. It is the direction every product points toward. How the mission turns into measurable objectives and concrete work is described in the [Goal-Setting Framework](../Ways-of-Working/Goal-Setting.md).
+
+## The three words
+
+Every decision is filtered through **easy**, **fast**, and **safe** — in tension, and on purpose.
+
+| Word | What it asks of every decision |
+| -------- | ------------------------------------------------------------------------------------------- |
+| **Easy** | Is the right thing also the easy thing? Is the safe, smart choice the default choice? |
+| **Fast** | Does this shorten the loop between intention and feedback? Can we ship a thinner slice now? |
+| **Safe** | Is this reversible? Is it observable? Will a failure teach us something instead of hurting? |
+
+The words pull against each other, and that is the point. Easy without safe is reckless. Safe without fast is paralysis. Fast without easy burns people out. Holding all three at once is the discipline.
+
+## AI-first, determinism-first
+
+Two beliefs sit underneath everything:
+
+- **AI is a first-class participant.** Agents are part of how we think, build, and deliver — not a feature bolted on at the end. Every workflow and every document is designed so an agent can read it and act.
+- **Determinism comes first.** A script that always produces the correct answer beats a prompt that usually does. We use AI to *build* deterministic tools, then run the tools. AI earns its place by handling what deterministic logic cannot — ambiguity, judgment, natural language, and search spaces too large for hand-written rules.
+
+The result is automation for the predictable and repeatable, and intelligence for the genuinely variable. Both, always available, each used where it is strongest. The full reasoning lives in [Principles → AI-first development](../Ways-of-Working/Principles/AI-First-Development.md).
+
+## How the vision cascades
+
+The vision is inherited, not copied. It is written once, here, and referenced everywhere:
+
+```text
+Vision (this site) the why — stable, evergreen
+└── Ways of Working the how — workflow, principles, conventions
+ └── Coding Standards the how, applied to code
+ └── Initiatives the what — the products
+ └── Repositories each README is the local source of truth
+ └── Agents read the same docs as context before acting
+```
+
+Each layer references the one above instead of restating it. A repository's README does not re-explain the principles — it links to them. An agent definition does not embed a style guide — it points to one. This keeps a single source of truth and lets the whole system evolve without drifting out of sync.
+
+## Where it comes to life
+
+A vision that stays on a page is just words. This one is meant to be *demonstrated*. Each initiative in the [Initiatives](../Initiatives/index.md) is a concrete answer to one question:
+
+> What would this look like if it were easy, fast, and safe?
+
+Go see the answers in the [Initiatives](../Initiatives/index.md).
diff --git a/src/docs/Ways-of-Working/Agentic-Development.md b/src/docs/Ways-of-Working/Agentic-Development.md
new file mode 100644
index 0000000..a2b31ee
--- /dev/null
+++ b/src/docs/Ways-of-Working/Agentic-Development.md
@@ -0,0 +1,83 @@
+---
+title: Agentic Development
+description: How ways of working, standards, and documentation are authored once and consumed by both humans and agents.
+---
+
+# Agentic Development
+
+How the ecosystem's ways of working, coding standards, and documentation are authored — and how both humans and agents consume them. The documentation defines how work is done; agent configuration *references* that documentation. It never the other way around.
+
+## Premise
+
+Process knowledge — how to open an issue, how to review a pull request, how Terraform is written — belongs in documentation, written once for two audiences. The temptation is to encode it as a tool-specific "skill" or instruction file, tightly coupled to one agent's format and scattered across repositories. That inverts the relationship and guarantees drift: the same rule, copied into many tool files, disagrees with itself the moment one copy changes.
+
+The specification fixes the direction of the dependency. The docs are the **stable core** that states how work is done. Agent configuration files are **thin pointers** to those docs — the same pages a new team member would read. Adding or swapping an agent runtime means writing new pointers, not rewriting process knowledge.
+
+## Principles
+
+This spec rests on the [Principles](Principles/index.md). Four apply directly:
+
+- **Written once, referenced everywhere.** A standard, a process, or a convention is defined in exactly one place and linked from everywhere else. Agent config, repository docs, and tool integrations point to that definition — they never duplicate it. This is [DRY](Principles/Software-Design.md#dry-with-judgment) applied to process knowledge.
+- **[Documentation lives close to the thing it documents](Principles/Engineering-Practices.md#documentation-lives-close-to-the-thing-it-documents).** Repo-specific context lives in the repository; cross-cutting guidance lives in the org-level docs and is referenced by its canonical URL. An agent always reads the repository's own context first.
+- **[AI-first development](Principles/AI-First-Development.md).** Humans create context — in issues, docs, and decisions — and agents act on it. Because agents are trained to read documentation, keeping standards in documentation form serves both audiences with a single artifact; no separate "agent manual" exists.
+- **[Extensible by default](Principles/Software-Design.md#extensible-by-default).** Ways of working and standards are the stable core. Coding agents are adapters that plug in. The system is pluggable: the docs do not change when a new runtime is added — only a new integration layer is written.
+
+## Architecture
+
+Agent configuration files are **pointers, not containers**. They tell the agent which human-readable files to read; they hold no process knowledge of their own. Documentation lives where it belongs — repo-specific docs in each repository's `README.md`, `CONTRIBUTING.md`, and `docs/`; cross-cutting standards in the org-level documentation site, referenced by canonical URL.
+
+When an agent starts work in a repository, it discovers context in layers — local first, then central, then local nuance on top:
+
+```mermaid
+flowchart TD
+ agent["Agent starts in a repository"] --> local["1 Read local context README.md · CONTRIBUTING.md · docs/"]
+ local --> index["2 Read the central indexes Ways of Working · Coding Standards · Capabilities"]
+ index --> pick["3 Pick up the relevant central docs e.g. the Terraform coding standard"]
+ pick --> nuance["4 Layer local overrides repo-specific instruction files"]
+ nuance --> work["Start work"]
+```
+
+The flow is sequential, not a decision. The agent reads local docs to understand the repository, reads the central indexes to see which shared standards exist, picks up the relevant ones, and finally checks for local overrides that add repo-specific nuance. **Local files never replace central standards — they layer specifics on top.** The docs are the stable core; every integration is a thin adapter that references them.
+
+## Where documentation lives
+
+Documentation is not collected into a single repository. Each page is authored and maintained where it naturally belongs:
+
+| Scope | Home | Examples |
+| --- | --- | --- |
+| **Cross-cutting** — ways of working, coding standards, capabilities | The org-level documentation site | This site: |
+| **Repo-specific** — architecture, setup, domain context | The repository that owns it | `README.md`, `CONTRIBUTING.md`, `docs/` |
+
+This split follows [Repository Segmentation](Repository-Segmentation.md) and [README-Driven Context](Readme-Driven-Context.md): the README is the front door of a repository, and the org-level site is the front door of the ecosystem.
+
+## How an agent runtime plugs in
+
+Agent context is delivered through three layers, in priority order — the same three layers the [Principles](Principles/AI-First-Development.md#human-agent-coexistence) describe:
+
+1. **Documentation.** The primary source. The published docs, READMEs, and issue bodies are written for humans and read natively by agents.
+2. **Central agent configuration.** Organization-wide agent files in a `.github-private` repository. These are thin orchestrators built mostly from references to the docs — they define roles, boundaries, and procedural steps, never standards or conventions.
+3. **Local repository files.** Per-repository instruction files for what is unique to a single repository, including the small amount of genuinely tool-specific configuration (permission scopes, path-scoped rules) that cannot be expressed as a pointer.
+
+Any new runtime follows the same pattern, regardless of vendor:
+
+- A **context file** that links to the ways-of-working docs and the repository's own context.
+- **Workflow entry points** — named commands or agents — that reference those same docs and add the operational steps (branch creation, tool invocations, API calls).
+- **Tool-specific settings** — permissions, model selection, and the like.
+
+The context file and the entry points are pointers; the settings are the only genuinely tool-specific surface. When a new runtime is adopted, only this integration layer is added — the documentation it points to is untouched.
+
+## Distribution
+
+The two non-documentation layers have different distribution models, set by the level at which the platform supports shared configuration:
+
+- **Org-wide agent files** are distributed through a central `.github-private` repository and are available across every repository in the organization with zero per-repo maintenance.
+- **Per-repository files** — context files and path-scoped instruction files — are seeded from a template repository and kept current across existing repositories by a sync mechanism.
+
+Process knowledge is never added to a distributed config file. If an agent needs the branch strategy, it goes in [Branching and Merging](Branching-and-Merging.md) or the repo's `CONTRIBUTING.md`; if it needs a coding convention, it goes in the relevant [coding standard](../Coding-Standards/index.md). The config file only points — it never defines.
+
+## Where this connects
+
+- [Documentation Model](Documentation-Model.md) — the discipline this specification follows.
+- [Principles](Principles/index.md) — the beliefs this specification rests on, including the three-layer agent context model.
+- [README-Driven Context](Readme-Driven-Context.md) — why the repository's own context comes first.
+- [Coding Standards](../Coding-Standards/index.md) — the cross-cutting standards agents pick up in the central layer.
diff --git a/src/docs/Ways-of-Working/Branching-and-Merging.md b/src/docs/Ways-of-Working/Branching-and-Merging.md
new file mode 100644
index 0000000..c872582
--- /dev/null
+++ b/src/docs/Ways-of-Working/Branching-and-Merging.md
@@ -0,0 +1,35 @@
+---
+title: Branching and Merging
+description: Topic branches, pull-request-only integration, and merge models.
+---
+
+# Branching and Merging
+
+How changes move from a working branch into a protected branch. The model is small branches, pull-request-only integration, and a history that stays readable.
+
+## Topic branches
+
+- Work happens on short-lived branches cut from the default branch — one per issue. Each gets its own [worktree](Git-Worktrees.md).
+- Name branches `/-`, e.g. `feat/42-pagination` or `fix/99-null-context`. The type matches the change type.
+- Branches stay short-lived. The longer a branch lives, the further it diverges and the harder it is to merge.
+
+## Pull requests only
+
+- Protected branches are never pushed to directly. Every change arrives through a pull request — even a one-line fix.
+- A pull request is green before review begins. Automated checks run first, so reviewers spend their attention on judgment rather than on catching what CI catches. This is [shift left](Principles/Engineering-Practices.md#shift-left).
+- Keep pull requests small and focused: one deliverable, reviewable in a single pass.
+
+## Merge models
+
+Two models, chosen by the repository's deployment shape:
+
+- **Single-branch (trunk).** One protected branch, always deployable. Topic branches squash-merge into it for a linear history. Suited to applications and libraries that release from the trunk.
+- **Promotion (multi-environment).** Changes flow through environment branches (for example `dev` → `main`), each promotion gated by an approval. Suited to infrastructure where environments deploy in sequence.
+
+The choice follows from [repository segmentation](Repository-Segmentation.md): an app and an infrastructure stack don't share a model.
+
+## A readable history
+
+- Squash-merge a topic branch so each merged change is one coherent commit on the protected branch.
+- Delete branches after merge. Stale branches are noise.
+- Commit messages are direct and descriptive. See [Commit Conventions](Commit-Conventions.md).
diff --git a/src/docs/Ways-of-Working/Commit-Conventions.md b/src/docs/Ways-of-Working/Commit-Conventions.md
new file mode 100644
index 0000000..0210289
--- /dev/null
+++ b/src/docs/Ways-of-Working/Commit-Conventions.md
@@ -0,0 +1,64 @@
+---
+title: Commit Conventions
+description: How commit messages are written.
+---
+
+# Commit Conventions
+
+Commit messages serve two audiences: the engineer reading `git log` six months from now, and the agents trying to reconstruct what changed and why. Both need the same thing — **direct, descriptive messages** that say what was done.
+
+## Rules
+
+1. **State what was done or what the result is.** Imperative or declarative, both work.
+2. **No conventional-commit prefixes.** No `fix:`, `feat:`, `docs:`, `chore:`, `refactor:`, etc. The change type is captured at the PR level — repeating it on every commit adds noise without information.
+3. **No generic messages.** `Update for PR`, `WIP`, `fixes`, `more changes` — all forbidden. They erase traceability.
+4. **One logical change per commit.** Micro-iterative discipline. If a change touches three unrelated concerns, that's three commits.
+5. **Reference issues by number when natural** — but don't force it. `Fixes #N` belongs in the PR description, not every commit message.
+
+## Examples
+
+### Good
+
+- `Add reserved word validation to Lua parser`
+- `Correct hex float parsing for negative exponents`
+- `Update installation prerequisites in README`
+- `Remove deprecated export command`
+- `Switch pagination to link-header-based`
+- `Add regression test for null session context`
+
+### Bad
+
+- `fix: parsing bug` — prefix + vague.
+- `Update for PR` — meaningless.
+- `WIP` — never commit work that needs a placeholder message; squash or amend first.
+- `Refactor stuff` — vague.
+- `Changes` — ø.
+
+## Body (optional)
+
+A commit message body is fine for non-trivial changes that need context. Keep it short. Wrap at ~72 characters per line.
+
+```text
+Switch pagination to link-header-based
+
+The previous page-number approach hardcoded the page size, which
+breaks when the API returns the default. Link headers are what
+the GitHub REST API documents as the supported pagination
+mechanism.
+```
+
+## Why no conventional commits
+
+MSX classifies changes at the PR level via labels and the change-type field. The release note is generated from the PR description, not from commit messages. Conventional-commit prefixes inside the repo:
+
+- Duplicate information already captured elsewhere.
+- Encourage `chore:` and `refactor:` over descriptive messages.
+- Lock the repo into a tooling pattern (Commitizen, semantic-release) that MSX doesn't use.
+
+Direct, descriptive messages serve both engineers and agents without the ceremony.
+
+## When working with agents
+
+The Builder writes commits during the micro-iterative loop. Each commit covers one discrete change. The Responder writes commits when addressing review feedback — one commit per thread when practical, so the link between feedback and fix is preserved in history.
+
+Never let an agent commit with a placeholder message. If a commit can't be described in one clear line, the change is probably too broad — split it.
diff --git a/src/docs/Ways-of-Working/Continuous-Practices.md b/src/docs/Ways-of-Working/Continuous-Practices.md
new file mode 100644
index 0000000..2099dc2
--- /dev/null
+++ b/src/docs/Ways-of-Working/Continuous-Practices.md
@@ -0,0 +1,163 @@
+---
+title: Continuous Practices
+description: The Continuous X family, Continuous AI, and the DevOps Dojo pillars.
+---
+
+# Continuous Practices
+
+A map of the "Continuous X" practices, how Continuous AI extends them, and where each one comes from.
+
+## 1. The "Continuous X" Practices
+
+### Microsoft DevOps Dojo's eight pillars (White Belt)
+
+The cleanest authoritative taxonomy. From [DevOps Dojo White Belt Foundation](https://learn.microsoft.com/en-us/training/paths/devops-dojo-white-belt-foundation/):
+
+| # | Practice | What it covers |
+|---|----------|----------------|
+| 1 | Continuous Planning | Lean product, hypothesis-driven dev, backlog management, OKRs |
+| 2 | Continuous Integration | Trunk-based dev, automated build & test on every commit |
+| 3 | Continuous Delivery | Every commit potentially releasable; automated pipeline to prod |
+| 4 | Continuous Quality | Test pyramid, shift-left testing, code review, static analysis |
+| 5 | Continuous Security | Shift-left security, SAST/DAST/SCA, secrets, supply chain |
+| 6 | Continuous Operations | SRE, observability, SLOs, incident response, on-call |
+| 7 | Continuous Collaboration | ChatOps, docs-as-code, transparent comms, shared ownership |
+| 8 | Continuous Improvement | Kaizen, retros, blameless postmortems, value-stream mapping |
+
+### Full inventory with provenance
+
+| Practice | Origin / canonical source |
+|----------|--------------------------|
+| **Continuous Integration** | Coined in Grady Booch's 1991 method; popularised by XP and [Martin Fowler's 2006 article](https://martinfowler.com/articles/continuousIntegration.html). |
+| **Continuous Delivery** | Jez Humble & David Farley, [*Continuous Delivery*](https://continuousdelivery.com/), 2010. |
+| **Continuous Deployment** | Every passing build deploys to prod with no human gate (vs. CD which only makes it *deployable*). |
+| **Continuous Testing** | Test throughout the pipeline plus in production (synthetic, canary analysis). |
+| **Continuous Verification** | Netflix's term for chaos-engineering-style continuous resilience validation. Rosenthal & Jones, [*Chaos Engineering*](https://www.oreilly.com/library/view/chaos-engineering/9781492043850/), O'Reilly. |
+| **Continuous Monitoring → Continuous Observability** | Shift from dashboards of knowns to ad-hoc querying of unknowns. [Honeycomb's Observability Manifesto](https://www.honeycomb.io/blog/observability-a-manifesto). |
+| **Continuous Feedback** | Right-to-left flow from prod → dev. DevOps Second Way (*Phoenix Project*). |
+| **Continuous Improvement** | Toyota *kaizen*; Deming PDCA cycle. |
+| **Continuous Learning** | DevOps Third Way (Kim, *Phoenix Project*). |
+| **Continuous Security / DevSecOps** | OWASP; [DoD Enterprise DevSecOps Reference Design](https://dodcio.defense.gov/Portals/0/Documents/DoD%20Enterprise%20DevSecOps%20Reference%20Design%20v1.0_Public%20Release.pdf). |
+| **Continuous Compliance** | Compliance-as-code: Chef InSpec, OPA, AWS Config. |
+| **Continuous Configuration Automation (CCA)** | Gartner term covering Ansible/Puppet/Chef/Salt. |
+| **Continuous Inspection** | SonarSource's term for always-on code-quality scanning. [docs.sonarsource.com](https://docs.sonarsource.com/). |
+| **Continuous Profiling** | Always-on production profiling. Pyroscope/Grafana, Polar Signals, Google-Wide Profiling paper (2010). |
+| **Continuous Documentation / docs-as-code** | Write the Docs community; treat docs like code. |
+| **Continuous Experimentation** | A/B testing, hypothesis-driven dev. Kohavi et al., [*Trustworthy Online Controlled Experiments*](https://experimentguide.com/), 2020. |
+| **Continuous Discovery** | Teresa Torres, [*Continuous Discovery Habits*](https://www.producttalk.org/continuous-discovery-habits/), 2021. |
+| **Continuous Architecture** | Erder & Pureur, *Continuous Architecture in Practice*, 2021. |
+| **Continuous Refactoring** | XP practice; Fowler's [*Refactoring*](https://martinfowler.com/books/refactoring.html). |
+| **Continuous Reliability** | Vendor-popularised (Catchpoint, Gremlin); convergence of SRE + chaos + observability. |
+| **Continuous Code Review** | Modern PR workflows + always-on reviewers. |
+| **Continuous Training (CT)** in MLOps | Google's [MLOps Levels 1–2](https://cloud.google.com/architecture/mlops-continuous-delivery-and-automation-pipelines-in-machine-learning) — automatic retraining on fresh data. |
+
+---
+
+## 2. Continuous AI
+
+**Canonical source:** [GitHub Next — Continuous AI](https://githubnext.com/projects/continuous-ai/), published June 2025 by Eddie Aftandilian, Peli de Halleux, Russell Horton, Don Syme.
+
+### Definition (verbatim)
+> "All uses of automated AI to support software collaboration on any platform."
+
+Positioned explicitly as the AI-era counterpart to CI/CD: *"Just as CI/CD transformed software development by automating integration and deployment, Continuous AI covers the ways in which AI can be used to automate and enhance collaboration workflows."*
+
+GitHub explicitly does **not** claim ownership of the term — it's a label for the industry, not a product.
+
+### Seven characteristics (GitHub Next's taxonomy)
+Continuous AI tasks are: **automatable, repetitive, collaborative, integrated, auditable, event-triggered**, and have **many variants**.
+
+### GitHub Next's example workflows
+- **Continuous Documentation** — docs in sync with code automatically
+- **Continuous Code Improvement** — comments, tests, small refactors
+- **Continuous Triage** — label/summarise/respond to issues in natural language
+- **Continuous Summarization** — rolling summaries of project activity
+- **Continuous Fault Analysis** — auto-explain failed CI runs
+- **Continuous Quality** — LLM-driven quality analysis
+- **Continuous Team Motivation** — PRs into poetry/zines/podcasts (the social layer)
+- **Continuous Accessibility** — auto-check & improve a11y
+
+### Continuous AI vs. its cousins
+
+| Term | What it is |
+|------|-----------|
+| **Continuous AI** | AI participating *in* the SDLC continuously (review, docs, triage, fault analysis). The AI is the actor. |
+| **MLOps** | CI/CD/CT *for* ML models — training, evaluation, deployment, monitoring. The model is the product. |
+| **LLMOps** | MLOps specialised for LLM apps: prompt versioning, evals, retrieval, guardrails, cost/latency monitoring. |
+| **AIOps** | AI/ML applied to IT operations — anomaly detection, alert correlation, RCA. Gartner term, ~2017. |
+
+### How Continuous AI augments each Continuous X practice
+
+| Traditional practice | Continuous-AI augmentation | Example tools (2025) |
+|---------------------|---------------------------|----------------------|
+| Continuous Integration | AI summarises broken builds; suggests fixes | GitHub Copilot Workspace, Sweep |
+| Continuous Delivery | Agents drive multi-step deploys; AI-authored release notes | GitHub Copilot agents, Devin |
+| Continuous Testing | Test generation, flaky-test detection, auto-repair | Diffblue, Qodo (CodiumAI), Meta TestGen-LLM |
+| Continuous Quality | LLM PR review beyond linters | CodeRabbit, Greptile, Graphite Diamond, Copilot review |
+| Continuous Security | LLM-aware SAST, auto-remediation PRs | Snyk DeepCode, Semgrep Assistant, Copilot Autofix |
+| Continuous Operations | "AI SRE" — autonomous triage, RCA, runbook execution | Resolve.ai, Cleric, PagerDuty AIOps, Rootly AI |
+| Continuous Documentation | Docs stay in sync with code | Mintlify, GitHub Next *Continuous Documentation* |
+| Continuous Code Review | Always-on AI reviewer | CodeRabbit, Greptile, Copilot review |
+| Continuous Refactoring | Background agents propose refactors | Cursor background agents, Sourcegraph Cody, Grit.io |
+| Continuous Triage | Issue labelling, dedup, summarisation | GitHub Models + Actions recipes, Linear AI |
+| Continuous Improvement | Auto-postmortems, retro summaries | incident.io, Rootly, Jeli (Atlassian) |
+| Continuous Discovery | LLM synthesis of user research | Dovetail AI, Maze AI |
+| Continuous Training (MLOps) | Pre-existed; now intersects with eval-driven LLM dev | Vertex AI, Databricks, Weights & Biases |
+
+### What structurally changes
+
+- **Evals are the new tests.** For AI features, regression suites are eval suites — graded by LLM judges or humans. Eval drift = test failure.
+- **Pipelines gain non-deterministic actors.** Every Continuous AI step needs auditability: which agent, which model version, which prompt, which tools, what did it touch.
+- **Cost and runaway risk.** Traditional CI steps have bounded cost; agentic steps can recurse. Need budgets, timeouts, concurrency caps.
+- **Prompt injection becomes a CI/CD threat.** Untrusted issue text, PR descriptions, error messages, third-party docs become attack surfaces when an agent reads them.
+- **Governance.** Expect "AI-generated change" to need provenance equivalent to a signed commit. SOC2/ISO27001/regulators catching up.
+
+### Tooling stack referenced by GitHub Next
+- [GitHub Actions](https://github.com/features/actions)
+- [GitHub Models](https://github.com/features/models)
+- [GenAIScript (Microsoft)](https://microsoft.github.io/genaiscript/)
+- [Datasette `llm`](https://llm.datasette.io/)
+- [GitHub Agentic Workflows](https://githubnext.com/projects/agentic-workflows/) — sister project at GitHub Next
+- [The Agentics](https://github.com/githubnext/agentics/) — example workflows
+
+---
+
+## 3. Microsoft DevOps Dojo — Status
+
+**Status:** alive but dormant. White Belt remains a real Microsoft Learn path; higher belts are blog posts; GitHub org quiet since late 2022.
+
+### History
+Started ~2018–2019 inside Microsoft (catalysed by a 2019 conversation with German CIOs); grew into a cross-org community spanning Services, Customer Success, Digital Advisory, and product groups. Public face was largely **April Edwards** (Senior Cloud Advocate). Authoritative intro: [*Intro of DevOps Dojo*](https://devblogs.microsoft.com/devops/intro-of-devops-dojo/) on Azure DevOps Blog (July 2022).
+
+### Belt curriculum
+- **White Belt** — standardised DevOps fundamentals — *only one with a formal Microsoft Learn path*
+- **Orange Belt** — scaled DevOps (enterprise/program/portfolio) — blog only
+- **Green Belts** — domain lenses (e.g. UX/Accessibility) — blog only
+- **Black Belt** — data-driven, intelligent DevOps for executives — never published
+
+Four pillars: Culture & Mindset, Lean Product, Architecture, Technology.
+
+### Where the content lives today
+
+**Microsoft Learn — White Belt (six modules):**
+- [DevOps Dojo White Belt Foundation](https://learn.microsoft.com/en-us/training/paths/devops-dojo-white-belt-foundation/)
+
+**Azure DevOps Blog (the deeper belts):**
+- [Intro of DevOps Dojo](https://devblogs.microsoft.com/devops/intro-of-devops-dojo/)
+- [People & Teams (Orange)](https://devblogs.microsoft.com/devops/devops-dojo-people-teams/)
+- [UX/Accessibility (Green)](https://devblogs.microsoft.com/devops/devops-dojo-ux-accessibility/)
+- [Culture and Mindset](https://devblogs.microsoft.com/devops/devops-dojo-culture-and-mindset/)
+- [Experiential Learning](https://devblogs.microsoft.com/devops/devops-dojo-experiential-learning/)
+- [Lean Product Part 1 / Part 2](https://devblogs.microsoft.com/devops/devops-dojo-lean-product-part-1/)
+
+**DevOps Lab video series:** [learn.microsoft.com/shows/devops-lab](https://learn.microsoft.com/en-us/shows/devops-lab/)
+
+**GitHub:** [github.com/microsoftdevopsdojo](https://github.com/microsoftdevopsdojo) — sparse, last meaningful activity Oct 2022.
+
+### What to use today
+1. **Dojo White Belt** on Learn — for the Continuous X scaffolding
+2. **[Evolve your DevOps practices](https://learn.microsoft.com/en-us/training/paths/evolve-your-devops-practices/)** — practical follow-on
+3. **[ISE Engineering Fundamentals Playbook](https://microsoft.github.io/code-with-engineering-playbook/)** — Microsoft's public, actively-maintained engineering playbook. The de facto modern equivalent.
+4. **[AZ-400 Enterprise DevOps](https://learn.microsoft.com/en-us/credentials/certifications/devops-engineer/)** — certification track
+
+The ISE Playbook is the more living artifact — updated regularly, public PRs welcome, covers similar ground without the belt theatre.
diff --git a/src/docs/Ways-of-Working/Contribution-Workflow.md b/src/docs/Ways-of-Working/Contribution-Workflow.md
new file mode 100644
index 0000000..1380954
--- /dev/null
+++ b/src/docs/Ways-of-Working/Contribution-Workflow.md
@@ -0,0 +1,108 @@
+---
+title: Contribution Workflow
+description: How a change travels from a branch to a review-ready pull request — draft first, the Copilot review loop, then people.
+---
+
+# Contribution Workflow
+
+How a change travels from a branch to a review-ready pull request. The workflow
+puts an automated Copilot review *before* human review: the author iterates with
+Copilot on a **draft** pull request until it has no more feedback, then opens the
+pull request for people.
+
+This is the operational "how". The conventions it builds on live in the ways of
+working — [Issue Format](Issue-Format.md), [PR Format](PR-Format.md),
+[Branching and Merging](Branching-and-Merging.md), and
+[Review Etiquette](Review-Etiquette.md).
+
+## The flow
+
+```mermaid
+flowchart TD
+ A[Branch and implement] --> B[Open PR as draft]
+ B --> C[Request Copilot review]
+ C --> D{New comments?}
+ D -- in scope --> E[Fix in this PR]
+ D -- out of scope --> F[File an issue]
+ E --> C
+ F --> C
+ D -- none --> G[Mark ready for review]
+ G --> H[Human review]
+```
+
+1. **Branch and implement.** Work on a `/` branch and keep the
+ per-change implementation detail in the issue and the pull request, not in the
+ spec or design.
+2. **Open the pull request as a draft.** A draft attaches CI and keeps the change
+ out of people's review queues while you iterate.
+3. **Run the Copilot review loop** (below) until Copilot reports a clean round —
+ no changes requested and no new inline comments.
+4. **Mark the pull request ready for review** once Copilot is clean and checks are
+ green. Human review takes over from there.
+
+## Why draft first
+
+- **Copilot is the first pass.** It catches the obvious issues quickly, so the
+ cheap feedback is spent before a person's time is
+ ([AI-First Development](Principles/AI-First-Development.md)).
+- **People review a self-reviewed change.** By the time someone is asked, the pull
+ request has already survived an automated pass and the author's responses —
+ review starts from a higher baseline.
+- **The draft is a safe workspace.** Force-pushes, rewrites, and rapid iteration
+ are fine while it is a draft; readiness is a deliberate signal.
+
+## The Copilot review loop
+
+Each round is the same: request a review, wait for Copilot, triage what it says,
+and repeat until it is clean. The waiting is deterministic, so it is scripted —
+`.github/scripts/Wait-CopilotReview.ps1` **explicitly requests** a Copilot review
+and polls until Copilot submits one, then reports whether it left inline comments:
+
+- exit `0` — a clean round: Copilot requested no changes and left **no new inline comments**;
+- exit `2` — Copilot has feedback (a new inline comment or a changes-requested review);
+- exit `1` — no review arrived before the timeout.
+
+```powershell
+# one round: request Copilot and wait for its verdict (-Verbose logs each step)
+./.github/scripts/Wait-CopilotReview.ps1 -Repository MSXOrg/ -PullRequest -Verbose
+```
+
+**Always request the review explicitly — never assume a ruleset or other
+automation will do it.** The script checks whether Copilot is already processing a
+request (from the timeline) and requests one only if not; a review "requested
+automatically" on push or on marking ready is not guaranteed to fire. Run a round
+after each push; the loop ends on a clean round (exit `0`). Copilot re-reviews the
+diff from scratch each round, so a genuine false positive can recur — do not
+change correct code to silence it; dismiss it with a reason and treat the loop as
+converged on substance.
+
+## Triage: fix in scope, file an issue for the rest
+
+For each piece of feedback, decide:
+
+- **In scope** — it concerns the change under review. Address it in this pull
+ request and push; the next round re-checks it.
+- **Out of scope** — it points at a pre-existing gap or an adjacent improvement.
+ File an issue ([Issue Format](Issue-Format.md)) capturing the gap and reference
+ it; do not grow the pull request to cover it.
+- **Not actionable** — a false positive, or a matter of taste you disagree with.
+ Reply with the reason and resolve the thread; a documented dismissal counts as
+ handled ([Review Etiquette](Review-Etiquette.md)).
+
+Keeping out-of-scope work in its own issue is what stops a focused change from
+sprawling — the pull request stays reviewable, and the gap is recorded rather than
+lost.
+
+## Marking ready
+
+When the loop is clean and lint and any required checks are green, mark the pull
+request **ready for review**. Readiness is the author's signal that the change has
+passed the automated pass and is ready for people — see
+[Review Etiquette](Review-Etiquette.md) for what a reviewer is accountable for.
+
+## Where this connects
+
+- [Workflow](Workflow.md) — the spec-led loop this operates within.
+- [PR Format](PR-Format.md) — the pull request title, description, and labels.
+- [Branching and Merging](Branching-and-Merging.md) — the branch model a pull request builds on.
+- [Review Etiquette](Review-Etiquette.md) — how human review proceeds once the pull request is ready.
diff --git a/src/docs/Ways-of-Working/Definition-of-Ready-and-Done.md b/src/docs/Ways-of-Working/Definition-of-Ready-and-Done.md
new file mode 100644
index 0000000..e3d8e4a
--- /dev/null
+++ b/src/docs/Ways-of-Working/Definition-of-Ready-and-Done.md
@@ -0,0 +1,36 @@
+---
+title: Definition of Ready and Done
+description: The two checklists that bracket every piece of work.
+---
+
+# Definition of Ready and Done
+
+Two checklists bracket every piece of work: one gates when it can start, the other gates when it can be called complete. Both are shared contracts, not personal preferences.
+
+## Definition of Ready
+
+An item is ready to be pulled into work when:
+
+- It is at the right level — a single deliverable, not a bundle. See [Issue Hierarchy](Issue-Hierarchy.md).
+- The intent is clear — the problem and the desired outcome are understood, written from the user's perspective.
+- It has acceptance criteria — "done" is described and testable.
+- It is sized to fit comfortably within one cycle of work.
+- Dependencies and blockers are known.
+- Open questions are resolved.
+
+Ready gates *starting*, not scope. An item that isn't ready stays in the backlog and gets refined — it is not pulled in and figured out on the fly.
+
+## Definition of Done
+
+An item is done when:
+
+- The acceptance criteria are met.
+- The change is merged through a reviewed pull request.
+- It conforms to the [Coding Standards](../Coding-Standards/index.md); linters and checks are green.
+- Tests cover the behavior and pass.
+- The [evergreen specification](Documentation-Model.md#evergreen-and-evolutionary) for the affected capability describes the new behaviour — the spec leads, the code matches it.
+- Documentation is updated in the same change — both owning-team docs (README, in-code help, and this site) and user-facing documentation.
+- It is released or deployed, where that applies.
+- No known regressions remain, and the issue is closed.
+
+Done is binary. Skip a criterion only when it genuinely does not apply — a docs-only change has no deploy step. If "done" repeatedly needs exceptions, fix the definition rather than quietly lowering the bar.
diff --git a/src/docs/Ways-of-Working/DevOps-Reference.md b/src/docs/Ways-of-Working/DevOps-Reference.md
new file mode 100644
index 0000000..c2ab6f2
--- /dev/null
+++ b/src/docs/Ways-of-Working/DevOps-Reference.md
@@ -0,0 +1,165 @@
+---
+title: DevOps Reference
+description: A curated reading list and the principles behind how we work.
+---
+
+# DevOps Reference
+
+A curated synthesis of authoritative sources, frameworks, and practices.
+
+---
+
+## 1. Essential Reading List
+
+### The Canon (Books)
+
+| # | Title | Author(s) | Year | Why it matters |
+|---|-------|-----------|------|----------------|
+| 1 | **The Phoenix Project** | Gene Kim, Kevin Behr, George Spafford | 2013 | The novel that introduced DevOps to mainstream. Source of the Three Ways. [itrevolution.com/product/the-phoenix-project](https://itrevolution.com/product/the-phoenix-project/) |
+| 2 | **The Unicorn Project** | Gene Kim | 2019 | Sequel from the developer's perspective; flow state, psychological safety, Five Ideals. |
+| 3 | **The DevOps Handbook** (2nd ed.) | Gene Kim, Jez Humble, Patrick Debois, John Willis | 2016/2021 | Practical companion to Phoenix Project. The reference implementation guide. |
+| 4 | **Continuous Delivery** | Jez Humble, David Farley | 2010 | Foundational technical text on CI/CD and deployment pipelines. [continuousdelivery.com](https://continuousdelivery.com/) |
+| 5 | **Accelerate** | Forsgren, Humble, Kim | 2018 | The science: rigorous research showing which practices actually drive performance. Origin of DORA metrics. |
+| 6 | **Team Topologies** | Matthew Skelton, Manuel Pais | 2019 | The four team types and cognitive load as a design constraint. [teamtopologies.com](https://teamtopologies.com/) |
+| 7 | **Lean Software Development** | Mary & Tom Poppendieck | 2003 | Lean manufacturing principles applied to software. |
+| 8 | **Out of the Crisis** | W. Edwards Deming | 1982 | Foundational systems thinking; 14 Points. The intellectual root of DevOps. |
+| 9 | **The Goal** | Eliyahu Goldratt | 1984 | Theory of Constraints. The novel format Kim borrowed for Phoenix Project. |
+
+### Google SRE Books — All Free Online
+
+All available at **[sre.google/books](https://sre.google/books/)**
+
+- **Site Reliability Engineering** (2016) — How Google runs production. SLOs, error budgets, toil, on-call, postmortems. [sre.google/sre-book/table-of-contents](https://sre.google/sre-book/table-of-contents/)
+- **The Site Reliability Workbook** (2018) — Practical implementation. [sre.google/workbook/table-of-contents](https://sre.google/workbook/table-of-contents/)
+- **Building Secure & Reliable Systems** (2020) — DevSecOps and resilient design. [google.github.io/building-secure-and-reliable-systems](https://google.github.io/building-secure-and-reliable-systems/raw/toc.html)
+
+---
+
+## 2. Core Principles
+
+### The Three Ways (from *The Phoenix Project*)
+
+1. **Flow** — Optimize the whole system, not silos. Reduce batch sizes, never pass defects downstream, build quality in early. → CI/CD, trunk-based dev, feature flags, WIP limits.
+2. **Feedback** — Amplify feedback loops right-to-left (ops → dev). → Observability, monitoring, SLOs, postmortems.
+3. **Continual Learning** — Culture of experimentation, blameless failure, deliberate practice. → Postmortems, chaos engineering, innovation time, game days.
+
+### Other Foundational Principles
+
+- **"You build it, you run it"** (Werner Vogels, Amazon) — Devs own their services in production. Shared on-call.
+- **Automation everywhere** — CI/CD, IaC, automated testing, security, compliance. Eliminate toil.
+- **Small batch sizes & trunk-based development** — Short-lived branches (<1 day), feature flags decouple deploy from release. [trunkbaseddevelopment.com](https://trunkbaseddevelopment.com/)
+- **Observability over monitoring** — Three pillars: logs, metrics, traces. Designed-in, not bolted on. [Honeycomb's Observability Manifesto](https://www.honeycomb.io/blog/observability-a-manifesto)
+- **Error budgets & SLOs** — Reliability is a feature with a cost. Aligns dev velocity and ops stability.
+- **Blameless postmortems** — Learning > blame. Focus on systems, not people.
+- **Shift-left security (DevSecOps)** — SAST, dependency scanning, secret scanning, IaC scanning in CI.
+- **Infrastructure as Code** — Version-controlled, peer-reviewed infra. Terraform, Pulumi, Kubernetes manifests + GitOps.
+
+---
+
+## 3. Frameworks Worth Knowing
+
+### DORA — Four Key Metrics
+The evidence-based standard for DevOps performance. Source: Forsgren/Humble/Kim research, now part of Google Cloud.
+
+| Metric | What it measures | Elite performance |
+|--------|------------------|-------------------|
+| **Deployment Frequency** | How often you deploy to prod | Multiple per day / on-demand |
+| **Lead Time for Changes** | Commit → production | < 1 hour |
+| **Change Failure Rate** | % of deploys causing problems | 0–15% |
+| **Mean Time to Restore** | Recovery from prod incidents | < 1 hour |
+
+A fifth metric — **Reliability** — was added in recent reports.
+
+- Latest research: [dora.dev/research](https://dora.dev/research/)
+- Annual State of DevOps Report: [cloud.google.com/devops/state-of-devops](https://cloud.google.com/devops/state-of-devops)
+
+### SPACE — Developer Productivity (Forsgren et al., 2021)
+DORA measures *delivery*; SPACE measures *productivity* holistically. Five dimensions spell **SPACE**: Satisfaction, Performance, Activity, Communication, Efficiency. No single metric works — need balance. [space-framework.com](https://space-framework.com/)
+
+### CALMS — DevOps Self-Assessment (Jez Humble)
+**C**ulture, **A**utomation, **L**ean, **M**easurement, **S**haring. Atlassian writeup: [atlassian.com/devops/frameworks/calms-framework](https://www.atlassian.com/devops/frameworks/calms-framework)
+
+### Team Topologies — The Four Team Types
+1. **Stream-aligned** — Owns a value stream end-to-end. The default team.
+2. **Platform** — Builds the IDP that stream-aligned teams consume.
+3. **Enabling** — Temporary coaches helping stream-aligned teams adopt new capabilities.
+4. **Complicated-subsystem** — Deep specialists (rarely needed).
+
+Plus three interaction modes: collaboration, X-as-a-service, facilitating. **Cognitive load** is the explicit design constraint.
+
+---
+
+## 4. How Good Teams Operate
+
+### Service Ownership
+One team owns a service from concept to retirement: code, deploys, on-call, SLOs, runbooks, DR, deprecation.
+
+### On-Call Health Markers
+- < 2 pages/week per engineer
+- MTTR < 30 min for typical incidents
+- Alerts are actionable (business-level, not "CPU > 80%")
+- Runbook for every alert
+- Clear escalation policy + secondary on-call
+- Time off after major incidents
+
+### Incident Response
+- Incident commander coordinates; scribe documents
+- Real-time war room (Slack channel + bridge)
+- Status updates every 15–30 min
+- Postmortem within 3–5 days, blameless, public, with tracked action items
+- Reference: [SRE Book — Postmortem Culture](https://sre.google/sre-book/postmortem-culture/)
+
+### Release Engineering
+- **Canary** — 5% → 25% → 100%, with auto-rollback on metric breach
+- **Blue/green** — Atomic cutover with instant rollback
+- **Feature flags** — Decouple deploy from release; LaunchDarkly, Unleash, Split
+- **Progressive delivery** — Combine canary + flags + experimentation
+
+### Observability Stack (one common shape)
+- Logs: ELK, Loki, Datadog, Honeycomb
+- Metrics: Prometheus + Grafana, Datadog, New Relic
+- Traces: Jaeger, Tempo, Honeycomb, Datadog APM
+- All correlated via trace ID propagated through services
+
+### Toil Reduction (SRE 50% rule)
+SREs spend ≤ 50% on toil; the rest on engineering away the toil. [SRE Book — Eliminating Toil](https://sre.google/sre-book/eliminating-toil/)
+
+### Platform Engineering (the modern evolution)
+Internal Developer Platforms (IDPs) are how mature orgs reduce cognitive load on stream-aligned teams. Self-service deploys, golden paths, paved roads. Communities:
+- [platformengineering.org](https://platformengineering.org/)
+- [humanitec.com](https://humanitec.com/) — research and benchmarks
+- CNCF TAG App Delivery — [github.com/cncf/tag-app-delivery](https://github.com/cncf/tag-app-delivery)
+
+---
+
+## 5. Where to Go Deeper
+
+### Authoritative organizations
+- **IT Revolution Press** — Gene Kim's publisher; DevOps Enterprise Summit talks (free): [itrevolution.com](https://itrevolution.com/)
+- **Google SRE** — [sre.google](https://sre.google/)
+- **DORA / Google Cloud** — [dora.dev](https://dora.dev/)
+- **CNCF** — Cloud-native landscape and definitions: [cncf.io](https://www.cncf.io/), [landscape.cncf.io](https://landscape.cncf.io/)
+- **ThoughtWorks Technology Radar** — Quarterly opinionated assessment: [thoughtworks.com/radar](https://www.thoughtworks.com/radar)
+
+### Vendor guides (well-written even if biased)
+- Atlassian DevOps Guide: [atlassian.com/devops](https://www.atlassian.com/devops)
+- GitLab — *The Remote DevOps Lifecycle*: [about.gitlab.com/topics/devops](https://about.gitlab.com/topics/devops/)
+- GitHub — *Well-Architected* and DevOps guides: [resources.github.com/devops](https://resources.github.com/devops/)
+- AWS DevOps: [aws.amazon.com/devops](https://aws.amazon.com/devops/)
+- Microsoft DevOps Resource Center: [learn.microsoft.com/en-us/devops](https://learn.microsoft.com/en-us/devops/)
+
+### Voices to follow
+- **Charity Majors** (Honeycomb) — Observability. Blog: [charity.wtf](https://charity.wtf/)
+- **Liz Fong-Jones** — SRE/observability practitioner
+- **Gene Kim** — DevOps movement, IT Revolution
+- **Jez Humble** — CD, Accelerate co-author
+- **Nicole Forsgren** — DORA/SPACE research lead
+- **Kelsey Hightower** — Cloud-native pragmatism
+- **Matthew Skelton & Manuel Pais** — Team Topologies
+- **John Willis** — Deming, DevOps history
+
+### Conferences worth watching (talks free on YouTube)
+- DevOps Enterprise Summit (DOES)
+- SREcon (USENIX)
+- KubeCon + CloudNativeCon
+- QCon
diff --git a/src/docs/Ways-of-Working/Documentation-Model.md b/src/docs/Ways-of-Working/Documentation-Model.md
new file mode 100644
index 0000000..aeacd67
--- /dev/null
+++ b/src/docs/Ways-of-Working/Documentation-Model.md
@@ -0,0 +1,144 @@
+---
+title: Documentation Model
+description: How every capability is documented — a spec for the why and a design for the how, colocated, concise, and kept evergreen for humans and agents alike.
+---
+
+# Documentation Model
+
+Documentation is a product, not a byproduct — and it is written once for two
+audiences, **humans and agents**. This page describes how the documentation on
+this site is organised so both find what they need fast: every capability is
+described by a **spec** and a **design**, kept side by side, kept short, and
+kept current as the system evolves.
+
+## A spec and a design for every capability
+
+Each capability the ecosystem builds is documented by two evergreen documents:
+
+| Document | Owns | Answers | Written for |
+| --- | --- | --- | --- |
+| **Spec** | Requirements, expectations, needs | **Why** it exists and **what** it must do | Whoever decides *whether* and *what* to build |
+| **Design** | Implementation approach | **How** and **what** we build to deliver the spec | Whoever *builds* and maintains it |
+
+The **spec** is the contract — the behaviour, guarantees, and success criteria a
+user (human or agent) can rely on. It never prescribes implementation. The
+**design** is the current answer to *how we deliver that contract*: the
+mechanism, the moving parts, the configuration. Both are durable, and both
+evolve — neither is a one-time plan.
+
+Only the detail of a *single change* — the paths touched, the trade-off taken
+this once — stays out of both, living in the [issue](Issue-Format.md) and the
+pull request where it belongs.
+
+## Capabilities live in folders
+
+Related docs sit together, and close to the thing they describe. Each capability
+is a folder holding its spec and design side by side:
+
+```text
+Capabilities/
+ release-management/
+ index.md # what this capability is
+ spec.md # the why + what
+ design.md # the how + what we build
+```
+
+A reader opens one folder and has the whole picture — the requirement and the
+implementation, one click apart. This is [Documentation lives close to the thing
+it documents](Principles/Engineering-Practices.md#documentation-lives-close-to-the-thing-it-documents)
+applied to the spec–design pair; where a design maps to a repository, the same
+two documents live with the code.
+
+## Why, what, how — a home for everything
+
+| Concern | Owned by |
+| --- | --- |
+| **Why / what** a capability must do | the capability's **spec** |
+| **How / what** we build to deliver it | the capability's **design** |
+| **How we work** — process, principles, conventions | [Ways of Working](index.md) |
+| **How code looks** — style applied to code | [Coding Standards](../Coding-Standards/index.md) |
+| **How this one change is implemented** — paths, trade-offs | the [issue](Issue-Format.md) and the PR |
+
+Keeping implementation out of the spec is what makes the spec durable:
+implementation detail rots fastest, so the spec leaves it to the design, and the
+design leaves per-change detail to the issue and the PR.
+
+## It starts with a need
+
+Every capability begins with a need and moves through a spec, then a design,
+then code — and loops:
+
+1. **Need** — a request, a bug, a review observation, a platform change.
+2. **Spec** — agree the next version's requirements: why it matters and what it
+ must do. Nothing is committed to building yet.
+3. **Design** — once committed to deliver, describe how and what we will build.
+4. **Build** — implement, evolving the design *and* the spec as development
+ teaches you things.
+5. **Operate** — running the system surfaces new needs, and the loop returns.
+
+```mermaid
+flowchart LR
+ Need(["Need (request, bug, signal)"]) --> Spec["Spec (why + what)"]
+ Spec --> Design["Design (how + what)"]
+ Design --> Build["Build (spec + design evolve)"]
+ Build --> Ops["Operate"]
+ Ops -->|new needs| Need
+```
+
+Both the spec and the design are **evolutionary**: development almost always
+changes your understanding, so you amend them in place rather than treating the
+first draft as fixed. The gap between the spec and what the system actually does
+is the work.
+
+## Evergreen and evolutionary
+
+Specs and designs are **evergreen**: written in the present tense as if the
+system already behaves as described, and amended in place as intent changes. Git
+history records what changed; the document records only what is true now.
+
+- **Declarative and present-tense.** It reads like a good README — a reader
+ trusts any line as the current contract.
+- **Normative.** Requirements use MUST / SHOULD / MAY so obligations are
+ unambiguous.
+- **No status, deltas, phasing, or open questions.** Those rot the moment they
+ are written; they belong in issues, PRs, and git history.
+- **Measurable success criteria.** A spec states outcomes a reader can verify —
+ *"a repository list returns every repository by default, with no silent
+ truncation"* — never *"the sync is fast."*
+
+Before a spec or design change is accepted it passes a quick rubric — is every
+requirement testable, are criteria measurable and implementation-free, is it
+present-tense and free of status? — applied in the reviewer's head and the PR
+([4-eyes](Principles/AI-First-Development.md#4-eyes-or-n-eyes-principle)), leaving no artifact behind.
+
+## Concise by default
+
+Respect the reader's attention — human or agent. A document earns nothing by
+being long.
+
+- **Short and scannable.** Lead with the point. Prefer a table or a list to a
+ paragraph. If a reader must scroll to find the rule, it is too long.
+- **One fact, one place.** State a thing once and link to it; never duplicate
+ ([DRY](Principles/Software-Design.md#dry-with-judgment)). Duplication is how docs begin to
+ disagree with themselves.
+- **Delete, don't stub.** A section that does not apply is removed, not marked
+ "N/A". Empty scaffolding hides the real content.
+- **Close together.** Related docs share a folder; docs sit near the code they
+ describe. Laziness is a design constraint — the less a reader must travel, the
+ more they actually read.
+
+## For humans and agents
+
+The same pages serve both. A contributor reads the index, follows the
+description inward, and drills from section to page until they reach the answer;
+an agent does exactly the same before it acts. Because the docs are the single
+source, there is no separate "agent manual" to drift —
+[Agentic Development](Agentic-Development.md) explains how agent configuration
+points at these pages rather than copying them.
+
+## Where this connects
+
+- [Workflow](Workflow.md) — the loop specs and designs revolve around.
+- [Agentic Development](Agentic-Development.md) — how humans and agents consume these docs.
+- [README-Driven Context](Readme-Driven-Context.md) — why the README is the front door and the spec goes ahead of the code.
+- [Coding Standards](../Coding-Standards/index.md) — how the code a design describes is written.
diff --git a/src/docs/Ways-of-Working/Engineering-Taste.md b/src/docs/Ways-of-Working/Engineering-Taste.md
new file mode 100644
index 0000000..d38c0e7
--- /dev/null
+++ b/src/docs/Ways-of-Working/Engineering-Taste.md
@@ -0,0 +1,37 @@
+---
+title: Engineering Taste
+description: The judgment that takes over when the standards run out.
+---
+
+# Engineering Taste
+
+Standards cover the common cases. When they run out, judgment takes over. These are the defaults for the decisions no rule can make for you.
+
+## Simplicity over cleverness
+
+- The simplest solution that solves the problem wins. Clever code impresses once and confuses forever.
+- Optimize for the next person to read the code. Assume they have no context — it might be a teammate, an agent, or you in six months.
+
+## Leave it better, but stay in scope
+
+- When you touch an area, leave it a little clearer than you found it — a better name here, a removed dead branch there.
+- Don't go hunting for unrelated cleanup. A focused change is easy to review and safe to revert; a sprawling one is neither. File the follow-up instead.
+
+## Don't build what you don't need
+
+- No over-engineering, no speculative generality, no abstraction with a single caller. Build for the requirement in front of you.
+- Reach for a general-purpose, proven tool before building a bespoke one. Boring and well-understood beats novel and clever.
+
+## Understand before you change
+
+- Read the existing code and its context before changing it. Most code is the way it is for a reason that isn't visible at first glance.
+- If you can't explain why the current code exists, you're not ready to replace it.
+
+## Weigh reversibility
+
+- Reversible decisions are cheap — make them quickly and move on.
+- Irreversible or expensive-to-undo decisions deserve more care: a second perspective and a written rationale. See [Principles → make change easy](Principles/Software-Design.md#make-change-easy-then-make-the-easy-change).
+
+## When still unsure
+
+Fall back to the three words: does this make the system **easier**, let us move **faster**, and keep us **safe**? If a choice trades one away, say so out loud and decide deliberately.
diff --git a/src/docs/Ways-of-Working/Evolutionary-Development.md b/src/docs/Ways-of-Working/Evolutionary-Development.md
new file mode 100644
index 0000000..501b6f4
--- /dev/null
+++ b/src/docs/Ways-of-Working/Evolutionary-Development.md
@@ -0,0 +1,157 @@
+---
+title: Evolutionary Development
+description: Grow software as bets under selection — variation, feedback, and survival of the fittest, run as one tight loop.
+---
+
+# Evolutionary Development
+
+Software is grown, not specified into existence. No one designs the right system up front; the hardest part of any change is deciding precisely what to build. So we treat every change as a **bet**: frame it, build the smallest thing that can be judged, expose it to real selection pressure, and keep what survives.
+
+This is Darwin's theory of evolution applied to engineering: variation, selection, and survival of the fittest. A design is not right because it was planned well; it survives because it fits the environment it has to live in — the tests, the users, the load, and the constraints. The outcome is non-deterministic: we direct the variation — the deliberate mutations — but real conditions, not our intentions, decide which design survives. It is neither blind natural selection nor a breeder's artificial selection: we choose what to try, the environment chooses what lives.
+
+Nature ran this algorithm first. We copy what it does well and set it on hyper-speed: cheap variation, ruthless feedback, and generations measured in minutes, not millennia.
+
+This standard is the *loop*, and it marries the practices we already keep. [Spec-Driven Development](Spec-Driven-Development.md) gives a bet its *shape* — the spec and its design, the *what* and *why*. Behavior-driven discovery turns that intent into Given / When / Then acceptance criteria — the definition of *fit*. Test-driven development grows the implementation against those criteria and the unit tests beneath them — the *how*, evolved in small steps. The three run as one loop. What drives it is not a particular hand but context in, criteria as the target, and feedback as the verdict — so the same loop turns whether a person runs it, an agent runs it, or agents run it end-to-end (see [How the loop is driven](#how-the-loop-is-driven)). It builds on [engineering practices](Principles/Engineering-Practices.md) (test-first where it pays, small batches, reversible decisions) and [AI-first development](Principles/AI-First-Development.md).
+
+## Why evolve instead of plan
+
+We state intent first and treat the plan as a living thing. Two habits carry it:
+
+- **Build shared understanding from concrete examples**, in rapid iterations, with documentation that is continuously checked against the system.
+- **Front-load the *why* and *what*** so both people and agents have the context they need, then refine continuously as understanding grows.
+
+Neither habit assumes the first design is correct. Both optimise the *loop*, not the plan: a big up-front design is a large, hard-to-reverse bet made when we know the least; a small slice under real feedback is a cheap bet made while we can still change our minds. Prefer the cheap bet.
+
+## The loop
+
+A change moves through one turn of selection. Each turn is small, and it repeats until the design survives.
+
+```mermaid
+flowchart LR
+ decide["Decide\nframe the bet · kill condition"] --> build["Build\nthinnest testable slice"]
+ build --> explore["Explore\nrun it · demo it · probe it"]
+ explore --> test["Test\nacceptance criteria = fitness"]
+ test --> feedback["Feedback\ntests · peers · production"]
+ feedback --> select{"Survives?"}
+ select -- "yes" --> retain["Retain\nmerge · record the decision"]
+ select -- "no" --> kill["Kill\ndelete · keep the learning"]
+ kill -.-> decide
+ retain -.-> decide
+```
+
+- **Decide.** State the bet as a hypothesis with an explicit kill condition — the result that would make us abandon it. Size the bet to its reversibility: local, reversible moves are cheap, so make them freely; one-way doors are expensive, so slow down and write them down ([decision before change](Principles/AI-First-Development.md#decision-before-change), [engineering taste](Engineering-Taste.md)).
+- **Build.** Make the smallest thing that can be judged — a walking skeleton or a throwaway spike — as a thin vertical slice, not a layer ([engineering practices](Principles/Engineering-Practices.md)).
+- **Explore.** Put it in front of reality: run it, demo it, probe its edges. Exploration is where surprises surface while they are still cheap.
+- **Test.** The [acceptance criteria](Spec-Driven-Development.md#acceptance-criteria) — Given / When / Then — are the coarse fitness function; the unit tests beneath them check the internals. They pass, or the bet has not survived. These automated tests become the guard-rails that stop later turns breaking earlier ones.
+- **Feedback.** Gather signal from the tests, from reviewers, and from production — the [delivery-performance signals](DevOps-Reference.md#dora-four-key-metrics) plus the one domain metric the change was meant to move.
+- **Select.** Keep what survives; kill what does not, fast. Deleting a slice that failed its test is a *result*, not a failure — the learning updates the spec. Retain a survivor by merging it through a decision point and recording any one-way-door choice as an ADR beside the spec.
+
+The loop turns until the design stops changing under feedback. Then the bet is settled (see [When a design survives](#when-a-design-survives)).
+
+## How the loop is driven
+
+Nothing in the loop is owned by a particular hand. What drives each turn is the same three things, whoever is turning it: **context** in, the **acceptance criteria** as the target, and **feedback** as the verdict. Give a turn those three and it can be run by a person, by an agent, or by agents end-to-end — increasingly the last, as context and criteria get sharp enough that a whole turn runs with no human in it.
+
+The unit of work is therefore a **well-scoped task** carrying exactly those three: the [context bundle](#context-first), the acceptance criteria that define done, and the fitness test to verify against. Output is judged against the criteria — the test is the oracle, not anyone's confidence — so the driver need not be trusted, only the test. Variation is cheap, so run **several bets in parallel** and let selection choose; keeping every branch alive is the anti-pattern.
+
+What does not move is the gate. Every change passes a [decision point](Principles/AI-First-Development.md#decision-before-change) before it reaches an environment, whether a person or an agent ran the loop — automation moves the work, never the accountability.
+
+## The two loops
+
+The loop above runs at two tempos at once, and the method keeps them distinct.
+
+```mermaid
+flowchart TB
+ subgraph outer["Outer loop · design · slow"]
+ spec["Spec and acceptance criteria"] --> slice["Pick a thin slice"]
+ slice --> build["Build it"]
+ build --> judge{"Fits its environment?"}
+ judge -- "no" --> spec
+ judge -- "yes" --> evolve["Ship · learn · evolve the spec"]
+ evolve --> spec
+ end
+ subgraph inner["Inner loop · implementation · fast"]
+ red["Red · a failing test"] --> green["Green · make it pass"]
+ green --> refactor["Refactor"]
+ refactor --> red
+ end
+ build -.-> inner
+```
+
+- **The outer loop evolves the design.** It is deliberate and coarse-grained: state the intent, agree the acceptance criteria, decide quickly, and let a slice meet reality. When feedback contradicts the intent, the spec changes first and the approach evolves — [spec-driven development](Spec-Driven-Development.md) turning. This is where early alignment, the acceptance criteria, and the one-way doors are settled. We dare to decide fast and fail fast here because the spec makes the cost of being wrong cheap to see and cheap to revise.
+- **The inner loop evolves the implementation.** It nests inside the **Build** stage and runs fast and fine-grained: write a failing test, make it pass, refactor, repeat — [test-driven development](Principles/Engineering-Practices.md#test-driven-development). The tests come at two grains — fine-grained **unit tests** for the internals and the **Given / When / Then acceptance tests** that encode the behavior from discovery. Many inner turns fit inside one outer turn, fast enough that variations are generated and discarded far quicker than by hand.
+
+The **acceptance criteria** couple the two loops. Written once as Given / When / Then, they are the outer loop's definition of *fit* and the inner loop's target — one behavioral statement serving discovery, the spec, and the test. Whoever turns each loop, the criteria keep both honest to the same intent.
+
+## Signals: the shapes of intent
+
+A turn does not only begin when someone asks for a feature. It begins with a **signal** — a pressure from the environment that the current design no longer fits — and every signal is **intent in a particular shape**. Naming the shapes keeps us honest that a bugfix, a performance guard, and a new capability are the same kind of work: a bet, framed from a signal, judged by selection.
+
+- **Need.** A request for functionality or capability the product does not have yet — a user, a stakeholder, or a dependent system pulling it forward. Intent stated outright: *make it do this.*
+- **Defect.** Proof that behavior and intent already disagree — a fault found in test or reported from production. An acceptance criterion that should hold does not, so the bet is to make it hold again.
+- **Operational signal.** Logs, traces, metrics, and incidents — the SRE evidence that the system is straining under real load. A rising error rate or a slow path is intent the users never had to type; the environment is speaking.
+- **Preventive analysis.** A proactive read that a design will not survive where it is heading — a performance cliff, a stability risk, a scaling limit seen before it bites. Intent inferred from the trajectory, not the pain.
+
+Wrapping them as **intents of different types** is the point: each enters the same loop, carries the same three drivers — context, acceptance criteria, feedback — and passes the same [decision point](Principles/AI-First-Development.md#decision-before-change). A defect is not a lesser feature and a preventive fix is not a luxury; each is a bet framed from a different signal, and each earns its keep only by surviving.
+
+## Discovery: finding and framing the bet
+
+Bets do not start from a solution; they start from a signal — need, defect, operational symptom, or risk — explored together. Discovery, formulation, and automation are how a [specification](Spec-Driven-Development.md) and its acceptance criteria are produced rather than guessed.
+
+- **Discovery.** Before pulling work in, hold a short, structured conversation about concrete examples. Map the story to its **rules** (the acceptance criteria), the **examples** that illustrate each rule, and the **questions** — the unknowns to resolve or defer. Time-box it; if the examples will not fit, the story is too big, so slice it. Three viewpoints must be present — the problem, the build, and the edge cases — covered by whoever is in the room, people or agents, drafting the rules and examples and surfacing the questions that need answering.
+- **Formulation.** Turn the agreed examples into Given / When / Then, in the shared language of the domain. This is the executable form of the acceptance criteria and the vocabulary that runs all the way into the code.
+- **Automation.** Connect each example to the system as a failing test, then build until it passes. The examples are living documentation: they describe what the system does today, and the build breaks the moment code and intent disagree.
+
+Discovery is the variation stage — where candidate behaviors are generated cheaply. Mark unknowns as `[NEEDS CLARIFICATION]` rather than guessing; a guess is an untested bet smuggled past selection.
+
+## Context first
+
+A turn is only as good as the context it runs on — output quality tracks input quality. The **context bundle** is the opening move of any turn, not an afterthought:
+
+- The [spec](Spec-Driven-Development.md) (why, what, acceptance criteria) and its design (how), or the marked unknowns where they do not exist yet.
+- The constraints, non-goals, and dependencies that bound the solution.
+- Pointers to the code, standards, and prior decisions that already apply — read in layers, local context before central standards ([Agentic Development](Agentic-Development.md)).
+
+This is [context-first development](Principles/AI-First-Development.md#context-first-development) made operational: the context is created up front — in specs, issues, and ADRs — and the loop runs on it. Context loss is the most common cause of wasted effort; a bet made without context is a bet made blind. Context is not read-only, though: when a turn shows a standard or instruction is wrong — or teaches a better one — updating it is part of the turn (see [The instructions evolve too](#the-instructions-evolve-too)).
+
+## The instructions evolve too
+
+> [!IMPORTANT]
+> Self-directed update is a standing directive, not an optional courtesy. Whoever turns the loop — a person or an agent — and learns something or hits a wrong instruction is expected to improve that instruction then and there, rather than leave it for someone else, so the next turn starts sharper than this one did. A loop that cannot improve its own instructions cannot evolve.
+
+The standards, guides, and agent instructions that inform how we work are part of the environment the loop runs in. They are context, and context drives every turn (see [How the loop is driven](#how-the-loop-is-driven)) — so a weak instruction misdirects every turn that reads it, quietly and at scale, and a sharper one improves every turn just as widely. The instructions are under selection too: correct them when they are wrong, and refine them when a turn teaches something better. Either way, updating them is part of the work, not a separate chore. This is [self-improving agents](Principles/AI-First-Development.md#self-improving-agents) applied to the instructions themselves.
+
+When a turn exposes a defect or discovers a better way of working — whether a person hits the friction or an agent does — raise the change as its own small bet and run it through the same loop: a change to the doc, reviewed and merged through a [decision point](Principles/AI-First-Development.md#decision-before-change). Signals worth acting on:
+
+- An agent needs the same clarification twice, or a `[NEEDS CLARIFICATION]` marker keeps recurring.
+- A review comment teaches a rule that is not written down yet.
+- An instruction contradicts how the work is actually done, or points at something that has moved.
+- A turn goes wrong in a way a clearer instruction would have prevented.
+- A turn finds a better way — a sharper prompt, a cleaner sequence, a rule worth making the default — worth keeping for the next one.
+
+Because a standard is defined once and pointed to everywhere ([Agentic Development](Agentic-Development.md)), one change propagates to every repo and every agent that reads it — improve it in one place and the whole fleet's behavior evolves. This is the method turned on itself: the same living-documentation discipline that keeps a spec true keeps the instructions true and refines them as we learn, so the way we work gets better every time a turn teaches us something worth keeping.
+
+## Working a v1
+
+A first version is where the least is known, so it is where evolution matters most. Start deliberately small and let the design earn its complexity.
+
+- **Minimal viable spec.** Write just enough intent and acceptance criteria to make the first bet falsifiable. Mark everything else as an open question rather than inventing an answer. The spec grows as reality teaches, not before.
+- **Walking skeleton.** Build the thinnest end-to-end slice that exercises the whole path — real inputs to real outputs — before thickening any single part. It proves the shape of the system while every decision is still cheap to undo.
+- **Explore a set, then converge.** For a decision that matters, try two or three approaches cheaply — parallel spikes — instead of committing to the first that occurs to you. Keep the survivor; delete the rest. Do not marry a design before it has beaten an alternative.
+- **Promote or kill.** A spike is disposable by default. It earns promotion only by passing its fitness test; otherwise it is deleted and what it taught updates the spec. A spike that quietly becomes production is a bet that skipped selection.
+- **Evolve the spec first.** When feedback contradicts the spec, the spec changes before the code — it is the source of truth, written in the present tense as the [intended state](Principles/Engineering-Practices.md#evergreen-documentation).
+
+## Bind to the practice, not the tool
+
+The toolchain is an adapter and it churns — runners get abandoned and replaced. Executable specifications outlive the tool that runs them: a feature written as Given / When / Then survives a change of runner untouched. Depend on the durable practice, not the tool — intent stated first, examples as Given / When / Then, living documentation checked in CI, and this loop. Tools slot in as thin adapters and can be swapped without rewriting the method ([extensible by default](Principles/Software-Design.md#extensible-by-default)).
+
+## When a design survives
+
+A bet is settled — it stops being an experiment and becomes the baseline — when:
+
+- its acceptance criteria pass and keep passing as guard-rails,
+- the domain signal moved the way the spec predicted,
+- no clarification markers remain, and
+- it is boring to operate — observable, and quiet under normal load.
+
+At that point the change meets the [Definition of Done](Definition-of-Ready-and-Done.md#definition-of-done) and the slice is retained. Further change to a settled design starts a new bet, and the loop begins again. Nothing is permanent: environments shift, and a design that no longer fits its environment is selected out — deprecated and deleted ([engineering practices](Principles/Engineering-Practices.md)).
diff --git a/src/docs/Ways-of-Working/Git-Worktrees.md b/src/docs/Ways-of-Working/Git-Worktrees.md
new file mode 100644
index 0000000..69f19fd
--- /dev/null
+++ b/src/docs/Ways-of-Working/Git-Worktrees.md
@@ -0,0 +1,119 @@
+---
+title: Git Worktrees
+description: Bare-clone and worktree layout for parallel, conflict-free work.
+---
+
+# Git Worktrees
+
+All repositories are set up as **bare clones with worktrees**. This enables parallel work — multiple agents (or a human and an agent) can work on different issues in the same repository simultaneously without conflicts, stashing, or context-switching.
+
+## Why worktrees
+
+| Problem with traditional clones | How worktrees solve it |
+| -------------------------------------------- | --------------------------------------------------------- |
+| Only one branch checked out at a time | Each issue gets its own worktree — parallel by default |
+| Switching branches requires clean state | Worktrees are independent — no stashing or committing WIP |
+| Agent work blocks human work on same repo | Different worktrees, no interference |
+| Default branch gets dirty during development | `/` worktree is always a clean reference |
+
+## Repository layout
+
+```text
+/
+├── .bare/ # bare git data (the actual repository)
+├── .git # file containing: gitdir: ./.bare
+├── / # worktree: default branch (always clean, never worked in directly)
+├── 42-add-pagination/ # worktree: issue #42 in progress
+└── 99-fix-null-ref/ # worktree: issue #99 in progress
+```
+
+- **`.bare/`** — the shared git object store. All worktrees share this.
+- **`.git`** — a file (not a directory) that points git tooling to `.bare/`.
+- **`/`** — the default branch worktree (e.g. `main` or `master`). Kept as a clean reference. Used for diffing, reading docs, running comparisons. Never directly committed to.
+- **`-/`** — one worktree per issue in flight. Named by issue number and a short slug. Branch name matches the folder name.
+
+## Remotes
+
+Every repository has exactly two remotes (or one, if it is not a fork):
+
+| Remote | Points to | Required | Purpose |
+| -------------- | ---------------------------- | -------- | ------------------------------------------------ |
+| **`origin`** | Our copy on the server | Always | Push branches, open PRs, CI runs against this. |
+| **`upstream`** | The parent repo (forks only) | Forks | Track upstream changes, sync the default branch. |
+
+No other remotes are added. This keeps the model simple and predictable for both humans and agents.
+
+### How it works in practice
+
+- **Non-fork repos** — only `origin` exists. Branches are pushed to `origin`, PRs are opened against `origin`.
+- **Forked repos** — `origin` is our fork, `upstream` is the original repository. The default branch tracks `upstream` for syncing; feature branches are pushed to `origin` and PRs are opened from `origin` into `upstream`.
+
+### Fetch configuration
+
+Both remotes are configured with full refspecs so `git fetch --all --prune` keeps everything current:
+
+```text
+[remote "origin"]
+ fetch = +refs/heads/*:refs/remotes/origin/*
+
+[remote "upstream"] # forks only
+ fetch = +refs/heads/*:refs/remotes/upstream/*
+```
+
+## Setup (one-time per repository)
+
+```powershell
+# Clone as bare into .bare/
+git clone --bare https://github.com//.git .bare
+
+# Create the .git pointer file
+Set-Content .git "gitdir: ./.bare" -NoNewline
+
+# Configure fetch refspec (bare clones don't set this automatically)
+git -C .bare config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
+
+# Fetch remote branches
+git -C .bare fetch origin
+
+# Determine the default branch
+$defaultBranch = git -C .bare symbolic-ref HEAD | ForEach-Object { $_ -replace 'refs/heads/', '' }
+
+# Create the default branch worktree
+git -C .bare worktree add "../$defaultBranch" $defaultBranch
+
+# Set upstream tracking (prevents "Publish Branch" prompt in VS Code)
+git -C .bare config "branch.$defaultBranch.remote" origin
+git -C .bare config "branch.$defaultBranch.merge" "refs/heads/$defaultBranch"
+```
+
+> The [Checkout-GitHubRepo](https://github.com/MariusStorhaug/.dev/blob/main/.github/Checkout-GitHubRepo.ps1) script automates this for all repositories.
+
+## Working on an issue
+
+```powershell
+# From the repo root (where .bare/ lives)
+$defaultBranch = git -C .bare symbolic-ref HEAD | ForEach-Object { $_ -replace 'refs/heads/', '' }
+git -C .bare worktree add ../42-add-pagination -b 42-add-pagination $defaultBranch
+
+# Set upstream tracking (prevents "Publish Branch" prompt in VS Code)
+git -C .bare config branch.42-add-pagination.remote origin
+git -C .bare config branch.42-add-pagination.merge refs/heads/42-add-pagination
+
+# Open in VS Code
+code 42-add-pagination
+```
+
+Then follow the normal Implement flow: initial commit → push → draft PR → build → finalize.
+
+## Cleanup after merge
+
+```powershell
+# Remove the worktree
+git -C .bare worktree remove 42-add-pagination
+
+# Delete the local branch ref
+git -C .bare branch -D 42-add-pagination
+
+# Prune if needed (removes stale worktree references)
+git -C .bare worktree prune
+```
diff --git a/src/docs/Ways-of-Working/Goal-Setting.md b/src/docs/Ways-of-Working/Goal-Setting.md
new file mode 100644
index 0000000..7bc7bb6
--- /dev/null
+++ b/src/docs/Ways-of-Working/Goal-Setting.md
@@ -0,0 +1,42 @@
+---
+title: Goal-Setting Framework
+description: Mission, OKRs, and initiatives — strategy connected to delivery.
+---
+
+# Goal-Setting Framework
+
+MSX uses a lightweight OKR-based framework to connect strategic direction to day-to-day work. The hierarchy runs from the organization's reason to exist down to individual deliverables tracked in GitHub issues.
+
+## Layers
+
+| Layer | Lives in | Purpose |
+| -------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------- |
+| **Mission** | Pinned issue in the org `.github` repository | The org's reason to exist — *make great software delivery the default: easy, fast, and safe* |
+| **OKR** | Sub-issues of the Mission | Qualitative objectives + measurable key results |
+| **Initiative** | Sub-issues of an OKR | A concrete bet to move a Key Result — becomes an Epic in a repo |
+
+## Why OKRs and not KPIs
+
+- **Objectives** are qualitative, aspirational, and outside-in. They describe a state of the world we want to see.
+- **Key Results** are measurements that confirm the Objective is being met. They drive incentive in the right direction without prescribing the path.
+
+A good OKR is one that anyone — contributor, user, or agent — can read and immediately have ideas about how to contribute. See [Principles](Principles/index.md) for the full rationale.
+
+## Current OKRs
+
+OKRs are tracked as sub-issues of the Mission issue in the org `.github` repository. They evolve over time; the direction they encode stays constant:
+
+- Every developer — and every agent — ships with confidence.
+- Automation handles the mechanical, so human attention is spent on judgment.
+- AI is a first-class, reliable contributor to the work.
+
+## From strategy to delivery
+
+Initiatives are the bridge between strategy and execution. An Initiative is a sub-issue of an OKR and maps directly to an **Epic** in the relevant repository. From there it decomposes into PBIs and Tasks through the [Issue Hierarchy](Issue-Hierarchy.md).
+
+```text
+Mission (org-level, evergreen)
+└── OKR (qualitative objective + key results)
+ └── Initiative (concrete bet to move a KR)
+ └── Epic (in a repository) → PBIs → Tasks
+```
diff --git a/src/docs/Ways-of-Working/Issue-Format.md b/src/docs/Ways-of-Working/Issue-Format.md
new file mode 100644
index 0000000..ab98b49
--- /dev/null
+++ b/src/docs/Ways-of-Working/Issue-Format.md
@@ -0,0 +1,410 @@
+---
+title: Issue Format
+description: The three-section issue structure, formatting, and labels.
+---
+
+# Issue Format
+
+Every issue in the MSX ecosystem follows the same structure. The format makes issues:
+
+- **Readable** by anyone — human or agent — without prior context.
+- **Actionable** by an implementer without back-and-forth.
+- **Traceable** because decisions and changes are recorded.
+
+## Properties of every issue
+
+- **Every change has an issue.** Features, fixes, refactors, documentation, maintenance — all tracked as issues before work begins.
+- **The description is the single source of truth.** It reflects the current state of the work at all times. Decisions, scope changes, and approach changes are written directly into the description.
+- **Comments record change history only.** Each description update is accompanied by a comment summarizing what changed and why.
+- **Tone is impersonal.** No first-person ("I", "my") or second-person ("you", "your") language. Neutral references like "the user", "the developer", or passive constructions.
+- **External references are hyperlinks.** Every mention of an API, RFC, library, doc, or tool is a clickable `[text](url)` link. No bare URLs.
+- **No duplicates.** Existing issues are searched before creating or restructuring. Duplicates are consolidated or cross-linked.
+
+## Title
+
+A clear, imperative-mood statement of the work. Not a question, not a symptom.
+
+- Scope or area when it aids disambiguation: `release pipeline: Add retry logic to the publish step`.
+- No type prefixes (`[Bug]`, `[Feature]`) — labels handle categorization.
+
+### Well-formed
+
+- `Add pagination support to the repository list command`
+- `Fix null reference when the session context is not resolved`
+- `Update installation guide with prerequisites`
+
+### Malformed
+
+- `Bug in module`
+- `Please fix`
+- `WIP`
+
+## The three sections
+
+The description has three sections separated by horizontal rules (`---`), ordered from behavioural to architectural to tactical. The user need is understood before the technical discussion.
+
+| Section | Owner | Present in |
+| ------------------------- | --------------------- | ------------------------------------------------------------- |
+| 1 — Context and Request | Ideator → Clarifier | Every issue at every level (Task, PBI, Epic) |
+| 2 — Technical Decisions | Planner | Task always; PBI / Epic for decomposition rationale |
+| 3 — Implementation Plan | Planner | Task always (task list); PBI / Epic (links to children) |
+
+## Section 1 — Context and Request
+
+Describes the **user experience** — what someone wants, what isn't working, or what is missing. Written from the user's perspective, not the implementer's.
+
+Two parts:
+
+- **Context** — who the user is, what they're trying to accomplish, the situation.
+- **Request** — the problem or need, as the user experiences it.
+
+Answers:
+
+- What does the user want to do?
+- What is the user experiencing today (for bugs / gaps)?
+- What should the experience look like instead?
+- Why does it matter?
+
+Framing by work type:
+
+| Type | Framing |
+| -------------- | ------------------------------------------------------------------------------------ |
+| Feature | **Desired capability:** The desired capability from the user's point of view. |
+| Bug / Fix | **What happens:** / **What is expected:** Observed vs. expected behavior. |
+| Change request | **Current experience:** / **Desired experience:** The shift from the user's lens. |
+| Maintenance | **User impact:** How internal work improves reliability, speed, or correctness. |
+| Documentation | **What is confusing or missing:** The gap from a user trying to accomplish a task. |
+
+Elements per work type:
+
+| Element | Feature | Bug / Fix | Change request | Maintenance | Documentation |
+| ------------------------ | :-----: | :-------: | :------------: | :---------: | :-----------: |
+| Acceptance criteria | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Reproduction steps | | ✓ | | | |
+| Environment / version | | ✓ | | | |
+| Regression indicator | | ✓ | | | |
+| Known workarounds | | ✓ | ○ | | |
+| Error messages / logs | | ✓ | | ○ | |
+| Screenshots / visuals | ○ | ✓ | ○ | | ○ |
+
+✓ = present when applicable, ○ = optional
+
+Element definitions:
+
+- **Reproduction steps** — a [minimal reproducible example](https://en.wikipedia.org/wiki/Minimal_reproducible_example): exact steps, inputs, and commands that trigger the problem. Anyone can reproduce the failure without guessing.
+- **Environment / version** — tool version, runtime version, and operating system. Other relevant runtime details (host application, execution context) included as applicable. Omitted only when clearly version-independent.
+- **Regression indicator** — whether this previously worked, and in which version. If unknown, stated explicitly.
+- **Known workarounds** — any mitigation available today, even if ugly or incomplete.
+
+This section contains:
+
+- Context: user story or scenario, background, what the user is trying to accomplish
+- Request: the specific problem, gap, or desired change — as the user experiences it
+- Current vs. desired experience
+- Impact of not addressing this (data loss, confusion, blocked workflows)
+- Acceptance criteria — what "done" looks like from the user's perspective
+- Applicable work-type-specific elements from the table above
+- Links to related issues, PRs, or external references — every external resource is a clickable hyperlink
+
+This section **does not contain** file paths, function internals, API endpoints, or implementation patterns. Those belong in Section 2. The section is understandable by someone who has never read the source code.
+
+**Example (Bug / Fix):**
+
+```markdown
+The `repo list` command is used in automation to sync all repositories for an account.
+The script relies on getting the full list so it can detect new or removed repositories.
+
+## Request
+
+When `repo list` is run on an account with more than 30 repositories, only 30 results are returned.
+There is no indication that results are incomplete, so it appears as though the full list has been retrieved.
+The silent truncation causes scripts to miss repositories, which can go unnoticed for weeks.
+
+### Reproduction steps
+
+1. Create or use an account with more than 30 repositories
+2. Run `repo list`
+3. Count the returned objects — only 30 are returned regardless of total count
+
+### What is expected
+
+The command should return **all** repositories by default. If there is a way to limit results,
+it should be opt-in — not the default.
+
+### Environment
+
+- **Tool version:** 0.14.0
+- **OS:** Ubuntu 22.04 (Linux)
+
+### Regression
+
+This appears to have been the behavior since the initial release. Not a regression.
+
+### Workaround
+
+Calling the REST API directly with manual pagination returns all results.
+
+### Acceptance criteria
+
+- All repositories are returned by default, regardless of how many exist
+- Results can be limited with a parameter when only a subset is needed
+- No silent data loss — if something limits results, it should be explicit
+```
+
+**Example (Feature):**
+
+```markdown
+Automation scripts that publish releases to multiple registries currently call the `publish` command
+in a loop for each target. There is no built-in way to publish to several registries in a single invocation.
+
+## Request
+
+### Desired capability
+
+A `--registry` option on the `publish` command that accepts a list of registry names, publishing
+to each in sequence. If any single publish fails, the error should be reported per-registry
+without aborting the remaining targets.
+
+### Acceptance criteria
+
+- `--registry` accepts one or more registry names
+- Each target is attempted independently — a failure on one does not block the others
+- Output clearly indicates success or failure per registry
+```
+
+## Section 2 — Technical Decisions
+
+The technical choices that shape the plan. Sits between the user-facing request and the tactical plan.
+
+Why this section exists:
+
+- Different technical choices lead to fundamentally different plans — deciding upfront avoids rework.
+- Conscious, documented choices replace implicit assumptions buried in code.
+- Reviewers see the **reasoning** behind the plan, not just the plan itself.
+
+Structure:
+
+- Each decision is a bolded label or heading, followed by the chosen approach and a brief rationale.
+- Alternatives considered are included when they help explain the choice.
+- Open decisions are marked with `Open:` and resolved before the implementation plan is written.
+- When a decision changes later, this section is updated and a comment documents the change.
+
+Typical decision areas:
+
+- Where new code lives (paths, modules).
+- Patterns or conventions followed (e.g., "follow the existing pattern in the release command").
+- Naming choices.
+- Whether to extend or create new.
+- Dependencies on other functions, modules, or APIs.
+- Error handling strategy.
+- Breaking changes and backward compatibility.
+- Test strategy (unit, integration, mocks).
+
+**Example:**
+
+```markdown
+---
+
+## Technical decisions
+
+**Code placement:** New helper goes in `src/lib/` following the existing
+request-helper pattern. The public command stays in `src/commands/repository/`.
+
+**Pagination approach:** Use link-header-based pagination (`rel="next"`) rather than page-number incrementing.
+The REST API uses link headers consistently, and this avoids hardcoding page size assumptions.
+
+**Parameter naming:** Use `--limit` (consistent with common CLI convention) rather than
+`--max` or `--max-results`.
+
+**Breaking changes:** None. Default behavior changes from returning one page to returning all pages, but since the
+previous behavior was undocumented and returning incomplete data, this is treated as a bugfix rather than a breaking change.
+
+**Test approach:** Unit tests with mocked API responses. One test per scenario: single-page, multi-page, and `--limit` limiting.
+```
+
+## Section 3 — Implementation Plan
+
+The task-level roadmap. Implementers track progress here; reviewers use it to understand scope.
+
+Structure:
+
+- Every discrete piece of work is a checkbox: `- [ ]`.
+- Tasks are grouped under subheadings when work spans multiple areas (files, components, tests).
+- Each task is specific and actionable — file paths, function names, modules.
+- All tasks start unchecked. Checking happens during implementation.
+- Tasks are ordered logically — dependencies first, tests last.
+
+For PBIs and Epics, Section 3 is **a list of links to child issues**, not inline tasks. See [Issue Hierarchy](Issue-Hierarchy.md).
+
+**Example:**
+
+```markdown
+---
+
+## Implementation plan
+
+### Core changes
+
+- [ ] Add a paged-request helper in `src/lib/`
+- [ ] Update the `repo list` command to call the paged variant in `src/commands/repository/`
+- [ ] Add a `--limit` option with integer type and validation
+
+### Tests
+
+- [ ] Add unit test for single-page response
+- [ ] Add unit test for multi-page response
+- [ ] Add unit test for `--limit` option limiting results
+
+### Documentation
+
+- [ ] Update command help with new option documentation
+- [ ] Add example showing pagination usage
+```
+
+## Comments
+
+Every description update is accompanied by a comment. Comments preserve the change history so reasoning is not lost when the description is overwritten.
+
+A comment contains:
+
+- A brief summary line.
+- Bullet points detailing what was added, changed, or removed.
+- Any gaps or open questions that need input.
+
+**Example:**
+
+```markdown
+Structured the issue description into the standard three-section format.
+
+- Rewrote the context and request to separate user-facing behavior from technical details
+- Added technical decisions section based on codebase research
+- Created implementation plan with 6 tasks covering core changes, tests, and documentation
+- Open question: should `-First` default to unlimited or require explicit opt-in? Marked as open in technical decisions.
+```
+
+## Formatting
+
+Issues use [GitHub Flavored Markdown](https://github.github.com/gfm/) with the full feature set:
+
+- `- [ ]` / `- [x]` task lists.
+- Tables for comparisons, label definitions, decision matrices.
+- Fenced code blocks with language identifiers.
+- `>` blockquotes for callouts.
+- `> [!NOTE]`, `> [!TIP]`, `> [!IMPORTANT]`, `> [!WARNING]`, `> [!CAUTION]` alerts.
+- `……` collapsible sections.
+- `#123`, `@user`, and commit SHA autolinks.
+- Backtick-wrapped inline code for identifiers.
+- `---` horizontal rules between sections.
+- `[text](url)` links for all external references.
+- **No hard line breaks within a paragraph.** GitHub renders mid-paragraph newlines as spaces, which creates inconsistent visual spacing.
+
+## Complete example
+
+A fully structured bugfix issue:
+
+**Title:** `Fix silent truncation of results in the repo list command`
+
+**Labels:** `Patch`, `Bug`
+
+**Body:**
+
+```markdown
+The `repo list` command is used in automation to sync all repositories for an account.
+The script relies on getting the full list so it can detect new or removed repositories.
+
+## Request
+
+When `repo list` is run on an account with more than 30 repositories, only
+30 results are returned. There is no indication that results are incomplete, so it appears
+as though the full list has been retrieved. The silent truncation causes scripts to miss
+repositories, which can go unnoticed for weeks.
+
+### Reproduction steps
+
+1. Create or use an account with more than 30 repositories
+2. Run `repo list`
+3. Count the returned objects — only 30 are returned regardless of total count
+
+### What is expected
+
+The command should return **all** repositories by default. If there is a way to limit
+results, it should be opt-in — not the default.
+
+### Environment
+
+- **Tool version:** 0.14.0
+- **OS:** Ubuntu 22.04 (Linux)
+
+### Regression
+
+This appears to have been the behavior since the initial release. Not a regression.
+
+### Workaround
+
+Calling the REST API directly with manual pagination returns all results.
+
+### Acceptance criteria
+
+- All repositories are returned by default, regardless of how many exist
+- Results can be limited with a parameter when only a subset is needed
+- No silent data loss — if something limits results, it should be explicit
+
+---
+
+## Technical decisions
+
+**Code placement:** New helper goes in `src/lib/` following
+the existing request-helper pattern. The public command stays in
+`src/commands/repository/`.
+
+**Pagination approach:** Use link-header-based pagination (`rel="next"`) rather than page-number
+incrementing. The REST API uses link headers consistently, and this avoids hardcoding page
+size assumptions.
+
+**Parameter naming:** Use `--limit` (consistent with common CLI convention)
+rather than `--max` or `--max-results`.
+
+**Breaking changes:** None. Default behavior changes from returning one page to returning all pages,
+but since the previous behavior was undocumented and returning incomplete data, this is treated as a
+bug fix rather than a breaking change.
+
+**Test approach:** Unit tests with mocked API responses. One test per scenario: single-page,
+multi-page, and `--limit` limiting.
+
+---
+
+## Implementation plan
+
+### Core changes
+
+- [ ] Add a paged-request helper in `src/lib/`
+- [ ] Update the `repo list` command to call the paged variant in `src/commands/repository/`
+- [ ] Add a `--limit` option with integer type and validation
+
+### Tests
+
+- [ ] Add unit test for single-page response
+- [ ] Add unit test for multi-page response
+- [ ] Add unit test for `--limit` option limiting results
+
+### Documentation
+
+- [ ] Update command help with new option documentation
+- [ ] Add example showing pagination usage
+```
+
+## Labels
+
+Labels categorize. The category is never encoded in the title.
+
+| Label | Use for |
+| ----------- | ---------------------------------------------------- |
+| `Major` | Breaking changes |
+| `Minor` | New features or enhancements |
+| `Patch` | Small fixes or improvements |
+| `NoRelease` | Documentation, maintenance, CI/CD — no version bump |
+| `Bug` | Bug reports |
+| `Feature` | Feature requests |
+| `Question` | Questions or discussion |
+
+Issue **types** (Epic / PBI / Task) are GitHub-native and separate from labels — see [Issue Hierarchy](Issue-Hierarchy.md).
diff --git a/src/docs/Ways-of-Working/Issue-Hierarchy.md b/src/docs/Ways-of-Working/Issue-Hierarchy.md
new file mode 100644
index 0000000..c91fcf8
--- /dev/null
+++ b/src/docs/Ways-of-Working/Issue-Hierarchy.md
@@ -0,0 +1,123 @@
+---
+title: Issue Hierarchy
+description: Epic, PBI, and Task — the three operational levels.
+---
+
+# Issue Hierarchy
+
+Work in the MSX ecosystem is tracked using GitHub sub-issues to form a connected hierarchy from Epic down to individual deliverables. The level reflects **scope and aggregation**, not priority or complexity. We use **GitHub issue types** for the segmentation — not labels — so the relationships are first-class in the platform.
+
+Epics originate from Initiatives in the [Goal-Setting Framework](Goal-Setting.md).
+
+## Full hierarchy
+
+```text
+Epic (initiative from an OKR, repo-level)
+├── PBI (body of work, multiple PRs)
+│ ├── Task (one PR-sized deliverable)
+│ └── Task
+└── PBI
+ └── Task
+```
+
+GitHub supports up to **8 levels** of nested sub-issues and **100 sub-issues per parent**, which comfortably fits this model with room to spare.
+
+## The three operational levels
+
+| Level | Issue type | Scope | Output |
+| ------------------------ | ------------ | -------------------------------------------------- | ---------------------------------------------------------- |
+| **Task** | `Task` | One deliverable. One small reviewable PR. | Working software. |
+| **Product Backlog Item** | `PBI` | A body of work composed of multiple Tasks. | Tracking, delegation, oversight, visibility into progress. |
+| **Epic** | `Epic` | Strategic chunk needing multiple PBIs. | The co-planning artifact. Where OKRs become initiatives. |
+
+> The name **Product Backlog Item** is chosen for its neutral vibe — it works equally well for a feature, a fix, a refactor, or an internal capability. "Feature" implies user-visible value, which isn't always the case for the middle tier.
+
+## When to use each level
+
+### Task
+
+Use Task when:
+
+- The work has one clear deliverable.
+- The expected PR is small and reviewable in a single pass (rough guideline: under ~500 lines / 15 files).
+- One person (or one agent) can pick it up and finish it independently.
+
+A Task is the **default starting point**. Promote upward only when you discover the work is too big.
+
+### Product Backlog Item
+
+Use PBI when:
+
+- The work has multiple distinct deliverables, each of which would be its own PR.
+- The deliverables share a goal but can be sequenced or parallelized.
+- You want oversight over the body of work without prescribing the order.
+
+A PBI's children can themselves be PBIs (nested decomposition) when the inner deliverables also break into multiple chunks. Epic → PBI → PBI → Task is legitimate when the work demands it.
+
+### Epic
+
+Use Epic when:
+
+- The work spans multiple PBIs.
+- It maps to a strategic objective — an OKR, an initiative, an organizational goal.
+- Multiple teams or contributors should co-plan around it.
+
+> "As a business we want to deliver this. What do we collectively need to do?"
+
+That conversation lives on an Epic.
+
+## Nested decomposition
+
+Nesting is fine and expected:
+
+```text
+Epic (initiative, ties to an OKR)
+├── PBI (one body of work)
+│ ├── Task (one PR)
+│ ├── Task
+│ └── PBI (further breakdown when needed)
+│ ├── Task
+│ └── Task
+└── PBI
+ └── Task
+```
+
+The rule: **one Task = one PR-sized deliverable**. Everything above is for aggregation.
+
+## How to express the hierarchy
+
+Use GitHub's **sub-issue relationship** between issue types. This is a first-class GitHub feature — not just text references — and the Planner agent creates these relationships when decomposing.
+
+Text-level conventions on child issues:
+
+- `Parent: #N` at the top of Section 1 (a courtesy duplicate of the GitHub link).
+- `Blocked by: #M` when sequencing matters.
+- Acceptance criteria scoped to **just this child's slice**, not the parent's whole goal.
+
+## How the sections differ by level
+
+| Section | Task | PBI | Epic |
+| ------------------------ | ----------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- |
+| Section 1 (Context/Req) | The deliverable's user story | The grouped goal's user story | The strategic outcome — vision, why, the change in the world |
+| Section 2 (Decisions) | Implementation decisions | Decomposition rationale + interface decisions between children | Decomposition rationale + which PBIs and why |
+| Section 3 (Plan) | Checkbox task list | Linked list of child issues (Tasks and/or sub-PBIs) | Linked list of child PBIs |
+
+For Epics, Section 1 should explicitly contain the **Golden Circle framing**: Why, How, What. See [Principles → Golden Circle](Principles/Purpose-and-Direction.md#start-with-why-the-golden-circle).
+
+## Why three levels and not more
+
+Three is enough to:
+
+- Cover **strategic** (Epic), **tactical** (PBI), and **operational** (Task) horizons.
+- Match how teams co-plan in larger frameworks (SAFe, Nexus) without inheriting their ceremony.
+- Aggregate progress meaningfully — an Epic burns down as its PBIs complete; a PBI burns down as its Tasks complete.
+
+More levels create overhead. Fewer levels lose the ability to track progress across bodies of work.
+
+## Promotion and demotion
+
+A Task can be **promoted** to a PBI when it turns out to be bigger than expected. The Planner does this — Section 2 records the discovery, and the inline task list becomes child issues.
+
+A PBI can be **demoted** to a Task when decomposition reveals only one real deliverable. Close the would-be-children, fold their content into the Task's Section 3.
+
+Promotion / demotion always leaves a comment audit trail explaining the change.
diff --git a/src/docs/Ways-of-Working/PR-Format.md b/src/docs/Ways-of-Working/PR-Format.md
new file mode 100644
index 0000000..e1db6e9
--- /dev/null
+++ b/src/docs/Ways-of-Working/PR-Format.md
@@ -0,0 +1,186 @@
+---
+title: PR Format
+description: Pull request title, description, change types, and labels.
+---
+
+# PR Format
+
+Pull requests in the MSX ecosystem double as **release notes**. The description is written for end users of the solution, not for reviewers or developers. Implementation details go in a clearly separated technical section at the bottom.
+
+## Title
+
+```text
+ []:
+```
+
+- The **Icon** matches the change type.
+- The **Type** in brackets is one of: `Major`, `Feature` (Minor), `Patch`, `Fix`, `Docs`, `Maintenance`.
+- The **outcome** describes what changed from the end user's perspective. Never internal function names, class names, refactoring verbs.
+
+### Good titles
+
+- `🌟 [Major]: Legacy export command removed`
+- `🚀 [Feature]: Custom templates now supported`
+- `🩹 [Patch]: Default timeout value corrected`
+- `🪲 [Fix]: Parameter validation no longer fails on null input`
+- `📖 [Docs]: Installation guide updated with prerequisites`
+- `⚙️ [Maintenance]: Release workflow and dependencies updated`
+
+### Bad titles
+
+- `Add support for custom templates` — describes the action, not the outcome.
+- `Refactor parameter validation logic` — implementation language.
+- `Update stuff` — meaningless.
+
+## Change types
+
+| Type | Icon | Label | Description |
+| ----------- | ---- | ----------- | ----------------------------------------------------- |
+| Major | 🌟 | `Major` | Breaking changes that affect compatibility |
+| Feature | 🚀 | `Minor` | New features or enhancements |
+| Patch | 🩹 | `Patch` | Small fixes or improvements |
+| Fix | 🪲 | `Patch` | Bugfixes (Patch-level release impact) |
+| Docs | 📖 | `NoRelease` | Documentation changes only |
+| Maintenance | ⚙️ | `NoRelease` | CI/CD, build configs, AI/agent files, internal upkeep |
+
+### Detecting the change type
+
+The change type is decided in this order:
+
+1. **Explicit user input** — if the contributor / Shipper specified a type, use it.
+2. **Pre-1.0.0 rule** — projects with no version tags or latest tag below `v1.0.0` follow [SemVer §4](https://semver.org/#spec-item-4). Major is **never** auto-detected for pre-1.0.0 projects. Breaking changes there are classified as Minor (`0.x.0`).
+3. **Artifact-based inference** from the branch diff:
+
+ | Artifact type | How to recognize | Important files (affect artifact) | Non-important (framework / tooling) |
+ | ---------------------- | ------------------------------------------------------------- | -------------------------------------------------------------- | ---------------------------------------------------------------- |
+ | Library / Module | `src/` with the library's source and a package manifest | `src/**`, package manifest | `.github/**`, `*.md`, `tests/**`, `scripts/**`, `agents/**` |
+ | GitHub Action | `action.yml` at repo root | `action.yml`, `src/**` | `.github/**`, `*.md`, `tests/**`, `agents/**` |
+ | Reusable Workflow | `.github/workflows/` with callable workflows | `.github/workflows/**` | `*.md`, `tests/**`, `agents/**` |
+ | Infrastructure module | `*.tf` with input variables and outputs | `*.tf`, `*.tf.json` | `.github/**`, `*.md`, `tests/**`, `examples/**` |
+
+4. **Classification rules** (apply in order):
+ 1. **Docs** — all changes are documentation only.
+ 2. **Maintenance** — all changes are non-important for the artifact (no shipped change).
+ 3. **Patch** — important-file changes are small fixes or minor improvements.
+ 4. **Minor** — important-file changes add features without breaking.
+ 5. **Major** — important-file changes break backward compatibility (pre-1.0.0 → downgrade to Minor).
+
+If the branch contains both important and non-important changes, classify based on the important changes only.
+
+## Description structure
+
+Ordered, top to bottom.
+
+### 1. Leading paragraph — Summary
+
+A concise paragraph describing **what changes for the user**. Present tense, active voice. Never open with implementation language ("Refactored", "Updated class", "Added null checks").
+
+### 2. User-facing changes — sections with headers
+
+Organize by **what the user experiences**, not by what was changed internally.
+
+- `## Breaking Changes` — what stopped working or changed incompatibly (Major only).
+- `## New: ` — new things the user can do.
+- `## Changed: ` — existing behavior that now works differently.
+- `## Fixed: ` — problems now resolved.
+
+Under each header:
+
+- What the user can now do, or what changed for them.
+- What they need to do differently — migration steps, new parameters, changed defaults.
+- Examples or code snippets showing new usage.
+
+Do **not** mention internal function names, class names, private APIs, or refactoring decisions here.
+
+### 3. Technical details (optional)
+
+```markdown
+## Technical Details
+```
+
+For reviewers and maintainers. Not part of the release note. Include:
+
+- Which internal functions, classes, or files were changed.
+- Implementation approach and design decisions.
+- Backward compatibility notes for developers.
+- **Implementation plan progress** — cross-reference Section 3 of the linked issue. Which tasks does this PR complete? Which remain?
+
+Omit the section entirely if there's nothing noteworthy.
+
+### 4. Related issues
+
+A collapsible `` block at the very end of the description containing issue links. Always use fully qualified references (`Owner/Repo#N`) so links work across repositories.
+
+```markdown
+
+Related issues
+
+- Fixes Owner/Repo#123
+- Owner/OtherRepo#124
+
+
+```
+
+One bullet per linked issue. Use a [closing keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue) (`Fixes`, `Closes`, `Resolves`) when the PR fully addresses the issue. Otherwise, list the reference without a keyword to indicate a relationship without auto-closing.
+
+If no issue is linked: **stop**. PRs without issues break the workflow. Route back to the Ideator role or proceed only on explicit user confirmation. The Shipper enforces this.
+
+## Formatting
+
+- Paragraphs are written as a **single unbroken line**. GitHub renders mid-paragraph newlines as spaces.
+- The PR description is **the release note**. Write it for users, not reviewers.
+- If a linked issue exists, the PR title and description should align with the issue's user-facing framing and the Technical Decisions section (Section 2).
+
+## Example
+
+````markdown
+Repository objects now include custom properties directly — no separate API call needed. Queries that encounter missing or inaccessible resources now return partial results with warnings instead of failing entirely.
+
+## New: Custom properties on repository objects
+
+The `repo get` command now returns custom properties inline on the repository object. Previously, retrieving custom properties required a separate `repo properties` call.
+
+```text
+repo get --owner MyOrg --name MyRepo --format table
+```
+
+The `repo properties` command remains available if only the properties are needed.
+
+## Fixed: Queries no longer fail when a resource doesn't exist
+
+Commands that query a specific repository, enterprise, or release by name now return nothing instead of throwing when the resource doesn't exist. This makes them safe to use in conditional logic without error handling.
+
+## Technical Details
+
+- The repository model's custom-properties field is now a typed collection rather than an untyped object.
+- The GraphQL query layer splits error handling into partial-success (data + errors → warnings) and full-failure (errors only → terminating error) branches.
+- Null guards added to the repository lookup helpers.
+- Implementation plan progress: tasks 1–3 in #218 completed; task 4 (integration tests) remains.
+
+
+Related issues
+
+- Fixes Owner/Repo#218
+- Owner/Repo#219
+
+
+````
+
+## Drafts and readiness
+
+- The Shipper always creates the PR as **draft** so CI attaches immediately.
+- Marking ready for review is the contributor's decision — never the agent's.
+- Suggested gates before marking ready: tests pass locally, description finalized, no known issues.
+
+## Branches and commits
+
+- Branch naming: `/-`, e.g. `fix/123-pagination-truncation`.
+- Commit messages: plain, direct, descriptive. **No conventional-commit prefixes** (`fix:`, `feat:`, `docs:`). See [Commit Conventions](Commit-Conventions.md).
+- Self-review the staged diff before each commit. Unintended files (debug output, editor temp, credentials) get caught before they reach the remote.
+
+## Labels and assignment
+
+- Apply the change-type label.
+- Apply phase labels if the repo uses them (Planning, Implementation, etc.).
+- Assign the current user.
+- Request reviewers per `CODEOWNERS`; if none, fall back to repo defaults or skip.
diff --git a/src/docs/Ways-of-Working/Principles/AI-First-Development.md b/src/docs/Ways-of-Working/Principles/AI-First-Development.md
new file mode 100644
index 0000000..f3e11fc
--- /dev/null
+++ b/src/docs/Ways-of-Working/Principles/AI-First-Development.md
@@ -0,0 +1,110 @@
+---
+title: AI-first development
+description: Agents as first-class participants, determinism before intelligence, and how humans and agents share the work.
+---
+
+# AI-first development
+
+We practice AI-first development. AI agents are part of how we think, build, and deliver — not an afterthought bolted on at the end. Every workflow, every process, and every piece of documentation is designed with agents as first-class participants.
+
+That said, engineering is not fully non-deterministic. Our priority order is clear: **build deterministic software first, invoke AI where determinism falls short.** A script that always produces the correct answer is better than a prompt that usually does. AI fills the gaps that deterministic logic cannot cover — ambiguity, judgment, creativity, natural language, and tasks where the search space is too large for hand-written rules.
+
+The result: AI is always available, always integrated, always ready — but it earns its place by handling what deterministic tools cannot.
+
+## Determinism before intelligence
+
+LLM tokens are not the right tool for work that has a deterministic answer. Use agents to **build** the deterministic tool — a script, a library, a converter — and then run the tool. Don't burn tokens on work a function call can do.
+
+Practices:
+
+- If a problem has a closed-form solution, write code — not a prompt.
+- Use AI to generate the deterministic tool, then discard the AI from the runtime path.
+- Reserve AI for tasks that genuinely require reasoning, judgment, or natural language understanding.
+- Audit existing AI-powered workflows: can any step be replaced by a deterministic function?
+- AI is excellent for ad-hoc alignment work — "do X across all repos" — but the end goal is always to codify the result into repeatable, deterministic automation.
+
+## Human-agent coexistence
+
+The workflow is designed for humans and agents working side by side. Agents join a good human way of working — they do not replace it or require a parallel system. The operating model is **human-first, agent-augmented**.
+
+Agents are trained to read documentation. That is their natural skill. By keeping standards, conventions, and principles in documentation format we serve both audiences with a single artifact — no separate "agent manual" required.
+
+Agent context is delivered through three layers, in priority order:
+
+1. **Documentation** — the primary source. Published docs at , READMEs, and issue bodies are written for humans and naturally consumable by agents.
+2. **Central agent configuration** — organization-wide agent files in `.github-private`. Thin orchestrators built mostly from references to the docs. They define roles, boundaries, and procedural steps — not standards or conventions.
+3. **Local repository files** — `.github/` instruction files and repo-level overrides for what is unique to a single repository.
+
+## Augmentation, not replacement
+
+Agents amplify the team. They make us faster, more consistent, and free us from work that is mechanical. **Human in the loop** remains the default for decisions that matter.
+
+## Persona, not swarm
+
+Treat the agent ecosystem as one team mate. Many specialized roles, one cohesive bank of knowledge, one consistent voice.
+
+## Self-improving agents
+
+Agents need feedback and a way to process it. Every agent definition should evolve as we learn. Capture lessons in the agent definitions and in this docs section — don't let them live only in someone's head.
+
+## Integration and sensoring
+
+- **Integration** — the agent's ability to act on a platform as if it were human. GitHub, the editor, the terminal.
+- **Sensoring** — the agent's ability to notice that it is needed. Webhooks, scheduled checks, signals from the platform.
+
+## Context-first development
+
+Every change flows through context before it touches code:
+
+```text
+Intention of change → Update documentation → Update README → Update tests → Update code
+```
+
+Code echoes the docs, not the other way around. The README and the docs are the **specification**. Tests validate the interface we want to see. If a change isn't reflected in context first, the code has no contract to implement against — and agents have nothing to read.
+
+This means:
+
+- A new feature starts as a documented intent (issue, README update, or docs change) before any code is written.
+- Tests are written or updated to assert the interface the documentation describes — before the implementation exists.
+- A refactor updates the relevant documentation **first**, then the tests, then the code follows to match.
+- If the docs and the code disagree, the docs are wrong — fix the docs, fix the tests, then fix the code to match.
+
+This is what makes agentic development work at scale. Agents read context. If the context is stale or missing, the agent builds the wrong thing. Keeping context ahead of code is how we stay in control.
+
+See [README-Driven Context](../Readme-Driven-Context.md).
+
+## Context as a product
+
+The work of keeping context **right, evergreen, and declarative** runs alongside software delivery:
+
+- **Software delivery** produces code, tests, and releases using source control, CI/CD, and DevOps practices.
+- **Context maintenance** produces issues, decisions, READMEs, agent definitions, and documentation — and treats them as products that must be kept current.
+
+Both run continuously. Each iteration of software delivery produces context that needs maintenance; each iteration of context maintenance unblocks the next round of software work.
+
+See [Workflow](../Workflow.md) for how these connect in practice.
+
+## 4-eyes (or N-eyes) principle
+
+Every change benefits from a second perspective. With AI in the loop, that can be:
+
+- A human reviewing your work.
+- You bouncing ideas off an agent.
+- Multiple agents reviewing each other's output against the same standards.
+
+The goal is the same: catch what one perspective misses.
+
+## Code review as shared practice
+
+Pull request reviews are not just a quality gate — they are a cultural practice. Reviewing serves multiple purposes beyond catching defects:
+
+- **Learning and awareness.** Reviews spread knowledge across the team. A reviewer learns how a new area works; an author learns alternative approaches. Over time, the entire team develops a broader understanding of the codebase.
+- **Shared responsibility.** Both author and reviewer share ownership of the changes that land. The author is responsible for proposing a sound change; the reviewer is responsible for validating it meets the team's standards. Once merged, the change belongs to both — neither can disclaim it.
+
+This means reviews are not adversarial. They are collaborative. A reviewer who approves a change is co-signing it. An author who receives feedback is gaining a perspective they didn't have alone. Treat both roles with the seriousness they deserve.
+
+## Decision before change
+
+Every change passes at least one deliberate decision point before it takes effect. A pull request approval is a decision — the reviewer actively commits to the change alongside the author. A deployment approval is a decision before a release reaches a protected environment.
+
+The point is not ceremony; it is that nothing irreversible happens automatically and unwitnessed. At least one reviewed gate stands between a proposal and its effect.
diff --git a/src/docs/Ways-of-Working/Principles/Engineering-Practices.md b/src/docs/Ways-of-Working/Principles/Engineering-Practices.md
new file mode 100644
index 0000000..75603a9
--- /dev/null
+++ b/src/docs/Ways-of-Working/Principles/Engineering-Practices.md
@@ -0,0 +1,103 @@
+---
+title: Engineering practices
+description: Write it down, everything as code, evergreen docs, test-driven development, and shift-left quality.
+---
+
+# Engineering practices
+
+## Write it down
+
+If something is only in your head:
+
+- Nobody else can work with you on it.
+- You cannot reflect on it.
+- It can escape you and be lost.
+
+**Write it down.** Issues, decisions, plans, READMEs. Writing is how knowledge becomes shared and how agents can help.
+
+## Everything as code
+
+Everything — workflows, configuration, infrastructure, processes, agent definitions, even the docs you are reading — lives in source control. This is the bedrock of human-agent interaction. An agent can read code, change code, propose code. It cannot read what's only in someone's memory.
+
+## Code in code files
+
+Code lives in a file of its own language — not embedded as a string inside YAML, JSON, a heredoc, or a template. Code in its own file gets the full benefit of tooling: linting, formatting, type-checking, security scanning, tests, and editor support. The same code inlined into another format gets none of it.
+
+- When one language must invoke another, call out to a script file rather than inlining the script. A workflow step runs a checked-in script; it does not carry a shell program inside a YAML string.
+- Keep the host format declarative. Configuration declares *what*; the implementation it points to holds the *how*.
+
+## Documentation lives close to the thing it documents
+
+- Comment-based help lives next to the function.
+- README lives at the root of the repo.
+- Workflow guidance lives in the org-level docs (this site).
+- Decisions live in the issue that produced them.
+
+Distance between a thing and its documentation is the rate at which they drift apart.
+
+## Evergreen documentation
+
+Documentation describes the system as it **is**, in the present tense — not the history of how it got there. A reader (human or agent) should be able to trust any page as the current truth without knowing what changed or when.
+
+- Write the intended state as if it already exists. Cut hedging, status notes, and "we will" or "we did".
+- Describe behavior and intent, not the process of building them. A pull request that adds a capability documents the capability, not the act of adding it.
+- Keep task lists, TODOs, and change history in issues and pull requests — not in evergreen docs.
+- Define a thing by what it is, not by contrast with an abandoned alternative. Lead with the positive fact.
+- When something changes, edit the document in place so it stays current. Git history records what changed; the document records what is.
+
+This governs this site, every README, and every specification — and it is why a pull request description states what the change *contributes*, not the steps taken to produce it.
+
+## Intent is the source of truth
+
+The documented intent that lives in the default branch — the specs, the docs, the issue descriptions — is the source of truth for what the system is meant to be. The implementation is a *representation* of that intent: the running code is what the system currently is, not necessarily what it should be.
+
+Either can be wrong. The intent may be mistaken, stale, or unclear; the implementation may have drifted from a correct intent. So when the two disagree, do not assume which is at fault — **diagnose it**: is the intent wrong (fix the doc, spec, or issue), or is the implementation wrong (fix the code)? Update whichever is wrong so the two converge again. A mismatch is a signal to reconcile, not a reason to silently trust the code or blindly rewrite the doc.
+
+## Test-driven development
+
+Define the tests when you define the behavior. Update them when behavior changes. Tests are the executable specification.
+
+## Shift Left
+
+Move quality gates as early as possible in the development cycle. The later a problem is caught, the more expensive it is to fix — a failing test in the editor is free; a bug in production is not. Design solutions so that validation happens at the earliest possible moment, not as an afterthought.
+
+### Testable locally
+
+A developer (or agent) must be able to run the full test suite locally, without requiring cloud resources, special access, or environment secrets that can't be mocked. If you can't test it on your machine, you can't reason about it in your editor.
+
+This is a design constraint, not an optional addition. A solution that is untestable locally has a hidden cost that compounds with every change. When building new workflows, modules, or automation, ask early: *can someone run this locally?*
+
+### Pre-commit hooks
+
+Validation that runs automatically on `git commit` — before the change enters history and before a PR is opened. Pre-commit hooks close the gap between "I can test it locally if I choose to" and "it is always checked before it leaves my machine."
+
+Typical gates: linting, formatting, static analysis, secret scanning, and fast unit tests. Keep them fast enough to not interrupt flow — if a hook takes more than a few seconds, it will be bypassed.
+
+### Validatable in PRs
+
+Every pull request must trigger automated checks that verify correctness before a human review begins. Tests, linting, module analysis, or any other relevant gate must run in CI on each PR.
+
+A solution without PR validation shifts the cost of catching regressions onto reviewers — and reviewers miss things. Automation catches what humans don't, consistently and at no extra cost per PR.
+
+## Local testing for quick iterations
+
+Make it easy to build, test, and run locally. The inner loop is where most engineering time is spent — every second saved there compounds.
+
+Inner / outer loops to be aware of:
+
+- **Innermost** — write code, save, see result. Sub-second.
+- **Inner** — run tests, see result. Seconds to a minute.
+- **Outer** — push, CI, review, merge. Minutes to hours.
+- **Outermost** — release, deploy, user feedback. Days to weeks.
+
+Push work as far inward as it can go.
+
+## 1-2-Automate
+
+If you've done a thing twice, the third time it should be automated. Sometimes you already know — go straight to automation. Extreme automation is often the right starting point.
+
+## DevOps and SRE
+
+> You build it, you run it.
+
+Everything is continuous — development, integration, delivery, operation. The same team owns the system across the loop. Build the systems, the practices, and the teams that internalize this.
diff --git a/src/docs/Ways-of-Working/Principles/Planning-and-Delivery.md b/src/docs/Ways-of-Working/Principles/Planning-and-Delivery.md
new file mode 100644
index 0000000..04724af
--- /dev/null
+++ b/src/docs/Ways-of-Working/Principles/Planning-and-Delivery.md
@@ -0,0 +1,43 @@
+---
+title: Planning and delivery
+description: Roadmapping, lean delivery, and the loops that keep iteration fast.
+---
+
+# Planning and delivery
+
+## Roadmapping
+
+We plan in a 3×3 matrix:
+
+| | Now | Next | Later |
+| ------------ | ------------ | -------------- | -------------- |
+| Conceptual | Vision today | Vision next | Vision later |
+| Logical | Approach now | Approach next | Approach later |
+| Detailed | Tasks now | Tasks next | Tasks later |
+
+- **Now / Next / Later** are time horizons without firm dates.
+- **Conceptual / Logical / Detailed** are levels of fidelity.
+
+The detail increases as work moves from Later toward Now.
+
+## Lean Software Development
+
+Start very thin. Get the team's ideas flowing. Enable more people to contribute. Don't build for tomorrow's requirements (**YAGNI**).
+
+The iteration phases — and we move through them quickly, sometimes in parallel:
+
+1. **Spike / Experiment** — can this thing even be built?
+2. **Proof of Concept** — does the experiment survive contact with reality?
+3. **MVP** — first version we can run in production. Start collecting real feedback.
+4. **Improvements** — stabilize, add functionality, harden.
+
+The best feedback is the feedback from people who have seen the thing.
+
+## Ways of working
+
+One size does not fit all. The way we work follows the principles above, including the principle of evolving how we work.
+
+- **Start lean** with processes and ceremonies. Get to know each other and the work first.
+- **Scrum + Kanban hybrid** — dynamic cycles, no firm sprint end dates. A cycle is over when an Epic is delivered. Estimation is approximate; Epics themselves are kept lean.
+- **Limit Work in Progress.** Roughly three concurrent items per person is the typical ceiling for sustained focus.
+- **Extreme Programming** — pair programming (human + human, or human + agent) as a vehicle for learning, decision-making, review, and validation.
diff --git a/src/docs/Ways-of-Working/Principles/Purpose-and-Direction.md b/src/docs/Ways-of-Working/Principles/Purpose-and-Direction.md
new file mode 100644
index 0000000..686ad0a
--- /dev/null
+++ b/src/docs/Ways-of-Working/Principles/Purpose-and-Direction.md
@@ -0,0 +1,45 @@
+---
+title: Purpose and direction
+description: Why we build, who we build for, and the least-privilege stance under every decision.
+---
+
+# Purpose and direction
+
+## Start with Why — the Golden Circle
+
+Every piece of work — at every level — should be groundable in three concentric questions:
+
+- **Why** — what change in the world are we trying to make? Vision.
+- **How** — what approach do we take to make that change happen? Mission.
+- **What** — what concrete thing are we delivering right now? OKRs → initiatives → tasks.
+
+When an issue is being written, the **Why** belongs in the Context part of Section 1. The **How** belongs in Section 2 (Technical Decisions). The **What** belongs in Section 3 (Implementation Plan).
+
+## Product / service mindset
+
+We are building something for people who should **want** to use it. Without users, we are nothing. Every decision is filtered through: does this make the product more wanted, or less?
+
+## Build for all developers
+
+We target all platforms and all shells. Our code, scripts, workflows, and documentation must work regardless of whether the developer is on Windows, macOS, or Linux. Line endings, path separators, shell assumptions — none of these should silently break someone's experience. Repository configuration (`.gitattributes`, CI matrices, test environments) must reflect this.
+
+## Build for the modern engineer
+
+We build for engineers using the latest tools and platforms. We do not support deprecated or end-of-life software. Concretely: we target current, cross-platform, actively-developed runtimes — not legacy editions frozen years ago. The same applies across the stack: latest stable releases, current LTS versions, modern APIs. If a tool has a successor, use the successor.
+
+## Dogfooding
+
+Be the first customer of every service we build. But avoid full self-dependency on a service before it is proven — explore and use it in non-critical contexts first, then promote it as confidence grows.
+
+## Least-privilege
+
+Every identity — human, agent, or workflow — gets only the permissions it needs to complete its specific task, and nothing more. This applies to GitHub tokens, workflow permissions, API scopes, and agent capabilities.
+
+Concretely:
+
+- Workflow jobs declare `permissions` explicitly and as narrowly as possible. A job that only reads should never have write access.
+- Agents are scoped to the actions they are authorised to take. An agent that reviews code should not be able to merge.
+- Secrets and tokens are never passed wider than the step or job that needs them.
+- When a required scope expands, that expansion is a deliberate, reviewed decision — not a default or a shortcut.
+
+The goal is to limit blast radius. If an agent, token, or job is compromised or behaves unexpectedly, least-privilege ensures the damage is contained.
diff --git a/src/docs/Ways-of-Working/Principles/References.md b/src/docs/Ways-of-Working/Principles/References.md
new file mode 100644
index 0000000..dfa90ed
--- /dev/null
+++ b/src/docs/Ways-of-Working/Principles/References.md
@@ -0,0 +1,17 @@
+---
+title: References
+description: The literature behind these principles.
+---
+
+# References
+
+Literature and books that inform these principles:
+
+- **Start With Why** — Simon Sinek. The Golden Circle framework (Why → How → What) that grounds our purpose-first approach. [simonsinek.com](https://simonsinek.com/books/start-with-why/)
+- **Measure What Matters** — John Doerr. The OKR framework we use for goal-setting — objectives over KPIs. [whatmatters.com](https://www.whatmatters.com/)
+- **Getting Things Done** — David Allen. The discipline of writing things down so they can be shared, reflected on, and acted upon. [gettingthingsdone.com](https://gettingthingsdone.com/)
+- **Clean Code** — Robert C. Martin. Readability, naming, and structure over cleverness.
+- **Refactoring** — Martin Fowler. Make change easy, then make the easy change.
+- **The Pragmatic Programmer** — David Thomas and Andrew Hunt. Evolutionary design, DRY, and automation as default.
+- **Accelerate** — Nicole Forsgren, Jez Humble, Gene Kim. The research behind DevOps, Shift Left, and continuous delivery.
+- **Lean Software Development** — Mary and Tom Poppendieck. Start thin, eliminate waste, deliver fast.
diff --git a/src/docs/Ways-of-Working/Principles/Software-Design.md b/src/docs/Ways-of-Working/Principles/Software-Design.md
new file mode 100644
index 0000000..08c78f4
--- /dev/null
+++ b/src/docs/Ways-of-Working/Principles/Software-Design.md
@@ -0,0 +1,45 @@
+---
+title: Software design
+description: SOLID, extensibility, DRY with judgment, and making change easy before making the change.
+---
+
+# Software design
+
+## SOLID — in plain language
+
+- **Single Responsibility.** One thing does one thing.
+- **Open / Closed.** Extend by adding, not by modifying what already works.
+- **Liskov Substitution.** If something derives from a base, it should be safely usable wherever the base is expected.
+- **Interface Segregation.** Don't make consumers depend on things they don't use.
+- **Dependency Inversion.** Depend on abstractions, not concretions.
+
+## Extensible by default
+
+Extend by adding, not by modifying what already works — the Open/Closed principle, applied beyond code to how the whole system grows. Ways of working and standards are the **stable core**; the tools that act on them — coding agents, runtimes, integrations — are **pluggable adapters** that slot in. Adding or swapping a tool means writing new pointers, not rewriting process knowledge.
+
+The system stays pluggable: the docs do not change when a new agent runtime is added — only a new integration layer is written. See the [Agentic Development](../Agentic-Development.md) specification for how this plays out in practice.
+
+## DRY — with judgment
+
+Don't Repeat Yourself, but **don't extract too early**. Wait until the same non-trivial logic appears in three or more places, or until the duplication is clearly load-bearing. Premature abstraction is more expensive than duplication.
+
+## Clean Code
+
+Write code that is understandable. Code is read more often than it is written. Names, structure, and intent come before cleverness.
+
+> Code should read like prose. It should tell a story that is easy to follow.
+
+## Evolutionary design / architecture
+
+Don't decide what you don't yet know. Experiment, iterate, treat design as a product — not a fixed contract. Architecture earns its right to be permanent by surviving change.
+
+## Make change easy, then make the easy change
+
+When a change is hard, resist the temptation to force it. First, restructure the system so the change becomes easy — as a separate, focused step. Then make the change itself. This separates two concerns:
+
+- **Prepare** — refactor, rename, extract, reorganise. No behaviour change.
+- **Change** — add, remove, or alter behaviour. No structural churn.
+
+Applied recursively: if the preparation step is also hard, first make that easy. Work like a zipper — each structural step unlocks the next, until the actual behaviour change is trivial.
+
+Keeping the two steps separate also lets you apply different levels of rigour. Structural changes are reversible — an extracted helper can be inlined again, a rename can be undone. Behaviour changes are often not — output sent, a form filed, a side effect triggered cannot be recalled. Irreversible decisions deserve more care. Separating the two gives you room to apply that care where it actually matters.
diff --git a/src/docs/Ways-of-Working/Principles/index.md b/src/docs/Ways-of-Working/Principles/index.md
new file mode 100644
index 0000000..26afc1c
--- /dev/null
+++ b/src/docs/Ways-of-Working/Principles/index.md
@@ -0,0 +1,27 @@
+---
+title: Principles
+description: The foundational beliefs and product mindset behind every decision.
+---
+
+# Principles
+
+The ideas underneath how we work — with each other and with our agents. These are evergreen; everything else on this site refers back to them.
+
+Principles are grouped by theme; each theme is its own page so an agent can load only the one it needs. Start here, then follow the theme that fits the task.
+
+
+
+| Page | Description |
+| --- | --- |
+| [Purpose and direction](Purpose-and-Direction.md) | Why we build, who we build for, and the least-privilege stance under every decision. |
+| [AI-first development](AI-First-Development.md) | Agents as first-class participants, determinism before intelligence, and how humans and agents share the work. |
+| [Software design](Software-Design.md) | SOLID, extensibility, DRY with judgment, and making change easy before making the change. |
+| [Engineering practices](Engineering-Practices.md) | Write it down, everything as code, evergreen docs, test-driven development, and shift-left quality. |
+| [Planning and delivery](Planning-and-Delivery.md) | Roadmapping, lean delivery, and the loops that keep iteration fast. |
+| [References](References.md) | The literature behind these principles. |
+
+
+
+## Why these principles matter
+
+These are the assumptions every agent decision rests on. When an agent's behaviour is unclear or contested, the answer comes from here. When something here turns out to be wrong, update this page — not just one agent.
diff --git a/src/docs/Ways-of-Working/Readme-Driven-Context.md b/src/docs/Ways-of-Working/Readme-Driven-Context.md
new file mode 100644
index 0000000..837f44d
--- /dev/null
+++ b/src/docs/Ways-of-Working/Readme-Driven-Context.md
@@ -0,0 +1,78 @@
+---
+title: README-Driven Context
+description: Why the README is the front door and the source of truth.
+---
+
+# README-Driven Context
+
+The README is the **evergreen context document** for every repository in the MSX ecosystem. It is the single source of truth for what a repository is, what it does, and how it works. Both humans and agents read the README before starting work — and update it whenever functionality changes.
+
+## Core principles
+
+- **The README is the front door.** Anyone — human or agent — encountering the repository for the first time should understand the purpose, scope, and current capabilities from the README without reading source code.
+- **The README is evergreen.** It is a living document that always reflects the current state of the repository. When functionality is added, changed, or removed, the README is updated in the same unit of work.
+- **Documentation is not optional.** A feature that is not documented in the README is effectively invisible. Updating the README is part of completing the work, not a follow-up task.
+- **The README is authoritative, but not automatically right.** It is the intended source of truth, yet a README can be wrong just as code can. When the README and the code disagree, [diagnose which is wrong](Principles/Engineering-Practices.md#intent-is-the-source-of-truth) — correct the README if the intent drifted, or fix the code if it diverged — so the two converge.
+
+## What belongs in the README
+
+Include what is relevant. Not every repository needs every section.
+
+| Section | Purpose |
+| -------------------- | -------------------------------------------------------------------------------- |
+| **Title** | Repository name as the top-level heading. |
+| **Description** | A concise summary (1–3 sentences) of what the repository does and who it is for. |
+| **Features / Scope** | A list or prose description of the capabilities the repository provides. |
+| **Getting started** | How to install, configure, or use the project for the first time. |
+| **Usage** | Examples and explanations of key functionality. Code samples where applicable. |
+| **Configuration** | Settings, environment variables, or options the user can control. |
+| **Architecture** | High-level overview — folders, components, data flow — for complex repos. |
+| **Contributing** | How to contribute, or a link to the organization-level contributing guide. |
+| **License** | License type or a link to the LICENSE file. |
+
+For simple repositories (e.g., a single GitHub Action), a subset is fine — at minimum the title, description, and usage sections.
+
+## When to update the README
+
+The README is updated **in the same pull request** that introduces the change. Documentation is part of the work — not a separate follow-up.
+
+### Update when
+
+- A new feature, command, function, or capability is added.
+- An existing feature changes in behavior, parameters, or output.
+- A feature, command, or option is removed or deprecated.
+- Installation or setup steps change.
+- Configuration options change.
+- The project scope or purpose evolves.
+- Architecture or folder structure changes significantly.
+
+### Do not update for
+
+- Internal refactoring with no user-facing impact.
+- Code style or formatting changes.
+- CI/CD changes that do not affect usage.
+- Dependency updates that do not change behavior.
+
+## Agent workflow
+
+When an agent works on a repository, the README sequence is:
+
+1. **Read the README first** — before reading source code, understand the project context.
+2. **Use the README as a guide** — let documented scope and architecture inform where and how to make changes.
+3. **Update the README as part of implementation** — same PR, not a follow-up.
+4. **Match the existing tone and structure** — heading levels, conventions, and style already present.
+5. **Don't delete without reason** — if something is outdated, update it rather than removing it, unless the feature no longer exists.
+
+## Writing guidelines
+
+- Write for a reader who has **no prior context**.
+- Use clear, direct language. Avoid jargon unless the audience is technical and the term is standard.
+- Use examples liberally — a code sample is worth a paragraph.
+- Focus on **what** and **how**, not implementation details. Internal design lives in code comments or architecture docs.
+- Follow the organization-wide Markdown style.
+
+## Why the README, and not this docs site
+
+This docs site (msxorg.github.io/docs) is the **organization-level** evergreen context — principles, workflow, standards. The README is the **repository-level** evergreen context — what this specific repo is and does.
+
+Both are required. The docs site explains how MSX works. The README explains what this repository is. An agent reading the docs site knows the system; an agent reading a README knows the project.
diff --git a/src/docs/Ways-of-Working/Repository-Segmentation.md b/src/docs/Ways-of-Working/Repository-Segmentation.md
new file mode 100644
index 0000000..3ed7a54
--- /dev/null
+++ b/src/docs/Ways-of-Working/Repository-Segmentation.md
@@ -0,0 +1,35 @@
+---
+title: Repository Segmentation
+description: What belongs in a repository, and when to split or combine.
+---
+
+# Repository Segmentation
+
+What belongs in a repository, and when to split or combine. The boundary of a repository is the boundary of ownership, versioning, and deployment — and therefore of a single responsibility, a single development lifecycle, and a single branch strategy. When those three align, the parts belong together; when any of them diverges, that divergence is the seam to split on.
+
+## One repository per independently-versioned thing
+
+- A repository holds one thing that is owned, versioned, and released as a unit. If two parts ship on different schedules or to different places, they are two repositories.
+- The test: can it be described in one sentence, owned by one team, and released on its own? If not, it is more than one repository.
+
+## Single responsibility — the S in SOLID, at repository scale
+
+- The [Single Responsibility Principle](Principles/Software-Design.md#solid-in-plain-language) is not only for classes. A repository, like a class, should have **one reason to change**: one responsibility, one deployable, one audience.
+- A module, an action, a service, an infrastructure stack — each is a single responsibility, so each is its own repository. When you cannot name a repository's responsibility in a sentence, it is holding more than one.
+- Resist both extremes: the monorepo of convenience that fuses unrelated responsibilities, and the micro-repo of habit that scatters one responsibility across many. Segment at the boundary of a thing that is built, versioned, and deployed as a unit.
+
+## Share a repository only when the development lifecycle is shared
+
+- Things that are **built, tested, released, and versioned together** belong in one repository; things whose lifecycles differ belong apart, even when they serve the same product.
+- The signal is the release: if changing one part forces the other to be re-released, they share a lifecycle; if it does not, they do not, and the boundary is real. Application code that compiles into an artifact has a different lifecycle from the infrastructure that provisions its environment, so they are separate repositories.
+- A shared lifecycle keeps the blast radius small: a change lands, is validated, and ships as one unit, without lockstep coordination across repositories.
+
+## Share a repository only when the branch strategy is shared
+
+- A repository's deployment model dictates its **branch strategy** — how changes flow, which branches are protected, and what approvals gate a release. Parts that share a branch strategy can share a repository; parts that need different ones cannot.
+- Code that promotes through environments needs a different flow from code that ships continuously from a single `main`. Forcing both models into one repository weakens both — one branch ends up over-gated, the other under-gated. See [Branching and Merging](Branching-and-Merging.md) for the models and how changes flow within a repository.
+
+## The boundary is self-describing
+
+- Every repository states, at its root, what it is, what it owns, and how it ships — in a README kept current with the code. See [README-Driven Context](Readme-Driven-Context.md).
+- Documentation and decisions live with the code they describe, so the repository boundary also bounds its own context instead of scattering it into a central store.
diff --git a/src/docs/Ways-of-Working/Review-Etiquette.md b/src/docs/Ways-of-Working/Review-Etiquette.md
new file mode 100644
index 0000000..bef1c87
--- /dev/null
+++ b/src/docs/Ways-of-Working/Review-Etiquette.md
@@ -0,0 +1,105 @@
+---
+title: Review Etiquette
+description: Tone, scope, severity, and how to disagree well.
+---
+
+# Review Etiquette
+
+How to disagree well, how to keep reviews focused, and how to keep the loop converging.
+
+## For the Reviewer
+
+### What to assess
+
+Consider each of the following dimensions when reviewing a PR:
+
+- **Functional** — Does the code meet the stated needs?
+- **Reliability** — Are we confident that the code will run failure-free?
+- **Performance** — Is the code as efficient as it can be?
+- **Usability** — Consider the user(s) of the service/product we provide; is the experience of high quality with this change?
+- **Security** — Are we improving the security posture of the service/product with the changes to the code? Are we worsening it?
+- **Maintainability** — Is the architecture good for future maintenance?
+- **Standards** — Is the code meeting coding standards for the project and language?
+
+### Stay in scope
+
+The PR delivers a specific issue. Suggestions that go beyond that issue are **new issues**, not blocking review comments. File the follow-up and link it from the comment.
+
+### One concern per comment
+
+Each thread is a scoped conversation. Bundling multiple unrelated nits into one comment makes it hard to resolve threads cleanly.
+
+### Be clear about severity
+
+Use explicit prefixes so the author knows what is blocking:
+
+- `Blocking:` — must be addressed before merge.
+- `Question:` — needs clarification; may or may not lead to a change.
+- `Suggestion:` — improvement worth considering; the author can take or leave it with reasoning.
+- `Nit:` — small style or preference issue; the author can dismiss freely.
+
+### Reason from evidence
+
+Cite the docs, the linter rule, the security advisory, the linked issue's Section 2. "It feels off" is rarely actionable. "This contradicts the decision in #N's Section 2" is.
+
+### Don't review your own PR publicly
+
+Self-review is fine and encouraged — but it goes to the terminal as a pre-flight report, not as GitHub comments on your own PR. (And by GitHub rules, you cannot `Request changes` on your own PR — submit a `Comment` review and use a blocking label if needed.)
+
+### Distinguish bots from humans
+
+Bot comments (linters, security scanners) tend to be factual. Human comments may carry context the bot can't infer — read them carefully and don't bulk-dismiss.
+
+## For the Responder (the author)
+
+### Reply before resolving
+
+Every resolved thread has a reply explaining the action — what was fixed, why dismissed, which issue picked it up. Bulk-resolving without replies looks like avoidance.
+
+### Forward progress over discussion
+
+A valid concern that needs deep design discussion becomes a follow-up issue and a resolved thread, not an open thread that blocks the PR. Open threads are blockers — minimize them.
+
+### Don't expand the PR
+
+The Reviewer suggested a thing that's out of scope. It's still out of scope. Reply, file the issue, link, resolve. Don't merge the suggestion in just to be polite.
+
+### Propagate fixes
+
+If a reviewer found a problem in one place and the same pattern exists elsewhere, fix it everywhere consistently. A partial fix that leaves identical problems in similar files is incomplete.
+
+### Test coverage gaps
+
+When a reviewer finds a real bug existing tests didn't catch, the fix is incomplete without a new or corrected test that closes the gap. Fixing only the source means the next regression is just as silent as this one.
+
+### Don't bulk-dismiss bot feedback
+
+Linter and security findings have a reason. Address them or suppress them with explicit justification — don't just silence them.
+
+## For both sides
+
+### Tone
+
+- Impersonal where possible. "This change does X" beats "You did X".
+- No sarcasm in writing — it doesn't travel well across time zones, languages, or human-agent boundaries.
+- Assume good intent. Both reviewer and author are trying to ship the right thing.
+
+### Disagreements
+
+When the Reviewer and Responder genuinely disagree:
+
+1. Re-state the disagreement plainly in the thread.
+2. Reference the relevant doc, decision, or principle.
+3. If still stuck, escalate to a human maintainer or file a discussion issue. Don't loop on the same thread.
+
+### Converge, don't diverge
+
+Every change in a review round should move the PR closer to merge. Avoid introducing new code that itself needs another review round. If a fix introduces a new design choice, surface it in the response and let the Reviewer accept it before piling further changes on top.
+
+### Stale comments
+
+If the code referenced by a comment has been modified since, mention it in the reply. Don't silently let stale comments accumulate as open threads.
+
+## What this is not
+
+This is not a process gate. It is **shared etiquette** so the loop is fast, professional, and respectful — across human reviewers, human authors, and the agents working alongside them.
diff --git a/src/docs/Ways-of-Working/Spec-Driven-Development.md b/src/docs/Ways-of-Working/Spec-Driven-Development.md
new file mode 100644
index 0000000..8e1e58c
--- /dev/null
+++ b/src/docs/Ways-of-Working/Spec-Driven-Development.md
@@ -0,0 +1,260 @@
+---
+title: Spec-Driven Development
+description: The specification is the source of truth — the spec (why and what), its design (how), and how a change moves from need to shipped.
+---
+
+# Spec-Driven Development
+
+Spec-driven development treats the specification as the source of truth: the spec captures *why* a change matters and *what* it must do, and everything downstream — design, tasks, code, tests — serves it. When intent changes, the spec changes first and the rest follows.
+
+This standard is the shape of a spec. It defines the artifacts of the method — the **specification** and its **design** — what each contains, at what level of detail, and how they move through the life of a change. It builds on the [evergreen documentation](Principles/Engineering-Practices.md#evergreen-documentation) principle (how a spec is written) and the [engineering practices](Principles/Engineering-Practices.md) (how we plan, build, ship, and measure).
+
+## The model
+
+A change moves down a ladder of artifacts. Each sits at a fixed altitude, is versioned in git, and lives beside the thing it governs. Higher layers are stable; lower layers are regenerated as understanding improves.
+
+| Layer | Answers | Altitude | Lives in | Changes when |
+|---|---|---|---|---|
+| **Need** | Is this worth doing? | one line | the request or issue | — |
+| **Spec** | Why, what, for whom, and what "done" means | implementation-agnostic | the capability folder, in the owning repo | intent changes |
+| **Design** | How it is built | technical, still readable | beside its spec (`design.md`) | the approach changes |
+| **Tasks** | In what steps | actionable | issues, at the levels of the [issue hierarchy](Issue-Hierarchy.md) | the plan changes |
+| **Code & tests** | The working expression | concrete | the codebase | continuously |
+
+```mermaid
+flowchart LR
+ need["Need\nrequest · incident · gap"] --> spec["Spec\nwhy · what · impact"]
+ spec --> design["Design\nhow"]
+ design --> tasks["Tasks\nepic → item → task"]
+ tasks --> code["Code & tests\nthe expression"]
+ code -. "production feedback" .-> spec
+```
+
+The spec is the durable artifact. Code is its expression in a particular language and framework; when the two disagree, the spec is what we meant and the code is what we did.
+
+## What a specification is
+
+A specification describes the intended state of one capability or feature — what is true when it exists, and why that matters. It reads true to a competent teammate who was not in the room, and it stays true after the code is refactored. Write it in the terse, present-tense, definitive style of [evergreen documentation](Principles/Engineering-Practices.md#evergreen-documentation).
+
+A spec **contains**:
+
+- **The problem and why now** — who is affected and what changes for them.
+- **Outcomes and impact** — the result in the world, and its expected effect on delivery (see [Impact](#impact)).
+- **Users and jobs** — who uses this and the job it gets done.
+- **Scope** — what is included, and an explicit list of what is out of scope.
+- **Requirements** — what the capability does and the qualities it must hold, functional and non-functional (see [Requirements](#requirements)).
+- **Acceptance criteria** — observable behavior that verifies the requirements (see [Acceptance criteria](#acceptance-criteria)).
+- **Constraints, assumptions, and dependencies** — the boundaries it respects and the work, access, or decisions it waits on.
+
+A spec **excludes** — this is the design's job:
+
+- Technology, frameworks, and libraries.
+- Architecture, components, and diagrams.
+- API shapes, schemas, and data models.
+- Algorithms and pseudo-code.
+- The task breakdown and rollout sequence.
+- Links to the code that fulfils it — implementations come and go.
+
+The altitude test: push detail *down* into the design, and push scope *up* into the epic. If a sentence would change when the team picks a different library, it belongs in the design, not the spec. This is the same rule the [Issue Format](Issue-Format.md) applies to issues — describe the *what* and *why*, never the *how*.
+
+## Requirements
+
+Requirements are testable statements of what must be true — never how it is built.
+
+**Functional** requirements describe what the capability does, as observable behavior. Number them so the design and the tests can trace back to each one.
+
+**Non-functional** requirements are the quality attributes the capability must hold — performance, security, reliability, availability, compliance, observability, and cost. State each as a measurable condition with a threshold; a non-functional requirement without a number is an opinion. For platform and infrastructure work these are often the point of the change rather than an afterthought — latency, redaction, retention, and blast radius decide whether the thing is fit to run.
+
+The [acceptance criteria](#acceptance-criteria) verify these requirements, and every requirement has at least one.
+
+## Acceptance criteria
+
+Acceptance criteria state observable behavior, written as Given / When / Then. They are the contract between the spec and the working system, the basis for the [Definition of Done](Definition-of-Ready-and-Done.md#definition-of-done), and they become the acceptance tests that verify the change.
+
+```gherkin
+Feature: Provider failover
+ Scenario: Primary provider is unavailable
+ Given the primary upstream provider is returning errors
+ When a client sends a request
+ Then the request succeeds through a healthy provider
+ And the response records which provider served it
+```
+
+Criteria describe effect, not mechanism — "requests succeed when the primary provider is down", not "a failover handler is added". Mechanism is the design's concern and must be free to change without rewriting the criteria.
+
+## Impact
+
+Every spec states the delivery impact it aims for, so the value is explicit before the work starts and measurable after it ships:
+
+- **DORA direction** — the expected effect on lead time for changes, deployment frequency, change-failure rate, and time to restore service (the [DORA four](DevOps-Reference.md#dora-four-key-metrics)). State the direction and reasoning, not a false-precision number.
+- **A domain signal** — one honest, measurable metric this change moves for the users of the capability.
+
+Estimate up front to align on why the work is worth doing; measure afterwards to learn. Production reality feeds back into the spec: a metric that misses, an incident, or a new constraint updates the spec for the next iteration.
+
+## What a design is
+
+The design is the specification's companion. It answers *how*, and it is free to change as often as the implementation does while the spec holds still. A design **contains** the approach and its rationale, the alternatives considered and why they were rejected, the architecture and components, the data and contracts other things depend on, the security boundaries and threats for new surfaces, the testing strategy, and the rollout and operability plan.
+
+One-way-door decisions taken in the design are recorded where they are made, following [Decision Before Change](Principles/AI-First-Development.md#decision-before-change), and kept as Architecture Decision Records beside the spec.
+
+## From need to shipped change
+
+The method is requirements-first. Work does not start from a solution; it starts from a need and earns its way down the ladder.
+
+1. **A need surfaces.** A stakeholder request, an incident, or a platform gap — or the team authors one when it sees the opportunity.
+2. **Draft the spec.** Capture the why, the outcome, and the requirements collaboratively. Agents draft, research context, and check the spec for ambiguity and gaps; humans supply the intent and make the calls ([AI-first development](Principles/AI-First-Development.md)). Unknowns are marked, not guessed (see [Authoring conventions](#authoring-conventions)).
+3. **Review the spec as a pull request.** The spec is versioned and reviewed like any change, following [PR Format](PR-Format.md) and [Review Etiquette](Review-Etiquette.md). Review argues about intent while it is still cheap to change.
+4. **Pass the readiness bar.** The spec is ready when it meets the [Definition of Ready](Definition-of-Ready-and-Done.md#definition-of-ready) — clear intent, testable acceptance criteria, no open questions that would change the approach.
+5. **Design and decompose.** Write the design, then break the work into the levels of the [issue hierarchy](Issue-Hierarchy.md) — an epic into smaller, independently deliverable items.
+6. **Build against the spec.** Implement in thin vertical slices, test-first where it pays, to the [Definition of Done](Definition-of-Ready-and-Done.md#definition-of-done) ([engineering practices](Principles/Engineering-Practices.md)). [Test-driven development](Principles/Engineering-Practices.md#test-driven-development) is an implementation practice governed by the coding standards and the Definition of Done, not something each spec re-specifies.
+7. **Feed reality back.** Metrics and incidents update the spec, and the cycle repeats.
+
+## Where specs and designs live
+
+A specification and its design live together in a folder named for the capability they describe, alongside an `index.md` — the [capability folder](Documentation-Model.md#capabilities-live-in-folders) pattern. The capability is owned by a component, and by default a component is a repository ([Repository Segmentation](Repository-Segmentation.md)), so the spec lives beside the code it governs ([docs live close to the code](../Coding-Standards/Documentation.md#the-hierarchy-of-documentation)):
+
+- **A component's own capabilities** → that repository's `docs/`.
+- **Cross-cutting capabilities** that span components → the central documentation hub.
+
+Splitting the spec from the design is what lets the spec stay stable across refactors while the design evolves with the code. How the docs are organized — the spec-and-design-per-capability shape and the folder layout — is the [Documentation Model](Documentation-Model.md).
+
+## Authoring conventions
+
+- **Write intended state.** Present tense, definitive, one fact stated once, as with all [evergreen documentation](Principles/Engineering-Practices.md#evergreen-documentation). No task lists, status, or history in the spec — those live in issues and PRs.
+- **Let git carry the record.** Created and updated dates, revision numbers, authorship, and the changelog are the repository's history, not fields in the document. Restating them in the body duplicates git and drifts out of date; the commits and the pull requests that reference the spec hold how it got here.
+- **Ownership is by location, not a byline.** The team that owns the code owns its spec ([docs live close to the code](../Coding-Standards/Documentation.md#the-hierarchy-of-documentation)); accountability lives in `CODEOWNERS`, not a per-document owner field that goes stale.
+- **Mark unknowns, do not guess.** Where the need is unclear, leave an explicit `[NEEDS CLARIFICATION: the specific question]` marker rather than a plausible assumption. All markers are resolved and removed before the spec is accepted.
+- **Self-review against a checklist.** Before review, confirm the spec is complete: no clarification markers remain, every requirement is testable, and the success criteria are measurable — a checklist is a unit test for the English.
+- **Keep it navigable.** The spec is readable in one sitting. Heavy detail moves into the design or a linked note, not the body.
+- **Reference, do not restate.** Point at the canonical standard or guide rather than copying it, so there is one source of truth and no drift.
+- **Links, not bare URLs.** Every external reference is a Markdown link, scoped the same way as in the [Issue Format](Issue-Format.md).
+
+## Templates
+
+Copy these skeletons to start a `spec.md` and its `design.md`. Every section is present so nothing is forgotten; delete a heading only when it genuinely does not apply.
+
+### Specification template
+
+````markdown
+#
+
+
+
+## Why
+
+
+
+## Outcomes and impact
+
+- **Outcome:**
+- **DORA:**
+- **Domain signal:**
+
+## Users and jobs
+
+
+
+## Scope
+
+**In scope**
+
+- <...>
+
+**Out of scope**
+
+- <...>
+
+## Requirements
+
+### Functional
+
+- **F1.**
+- **F2.** <...>
+
+### Non-functional
+
+- **N1.**
+- **N2.** <...>
+
+## Acceptance criteria
+
+```gherkin
+Scenario:
+ Given
+ When
+ Then
+```
+
+## Constraints and assumptions
+
+- **Constraint:**
+- **Assumption:**
+
+## Dependencies
+
+-
+
+## Open questions
+
+- [NEEDS CLARIFICATION: ]
+
+## Decisions
+
+
+````
+
+### Design template
+
+````markdown
+# — Design
+
+
+
+## Specification
+
+
+
+## Approach
+
+
+
+## Alternatives considered
+
+| Option | Trade-offs | Verdict |
+|---|---|---|
+|