diff --git a/.github/linters/.cspell.yml b/.github/linters/.cspell.yml
new file mode 100644
index 000000000..33ea8b6da
--- /dev/null
+++ b/.github/linters/.cspell.yml
@@ -0,0 +1,135 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json
+# docs: https://cspell.org/docs/getting-started
+# ------------------------------------------------------------------------------
+# This file is synced from the radius-project/.github repository.
+# DO NOT EDIT MANUALLY - changes will be overwritten by the next sync.
+# Source: https://github.com/radius-project/.github
+# ------------------------------------------------------------------------------
+---
+$schema: https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json
+version: "0.2"
+language: en
+
+# Built-in dictionaries plus the shared custom word list (.cspellignore at repo root).
+# This is the unified Radius spell-checking configuration; per-repository custom
+# words belong in the repo's own .cspellignore file, not in this synced config.
+dictionaries:
+ - softwareTerms
+ - companies
+ - python
+ - bash
+ - filetypes
+ - en_US
+ - cspellignore
+
+# Ignore patterns within files (sections that should not be spell-checked).
+ignoreRegExpList:
+ - code_block
+ - adr_yaml_formatter
+ - inline_code
+ - tf_docs
+ - md_link
+ - url
+ - at_mention
+ - html_tag
+ - email_address
+ - hugo_shortcode
+ - front_matter
+ - html_code_tag
+
+# Custom regex patterns so that fenced code, inline code, markdown links, URLs,
+# HTML and similar tokens are excluded from spell-checking.
+patterns:
+ # Fenced code blocks: ```lang ... ``` (with or without language identifier).
+ # Allows leading whitespace so indented code blocks inside list items match.
+ - name: code_block
+ pattern:
+ - /^[ \t]*`{3,}[^\n]*\n[\s\S]*?^[ \t]*`{3,}\s*$/gm
+ - name: adr_yaml_formatter
+ pattern:
+ - /(^([a-z-]*[:]{1})((\w|\s|,|"|-)*?)$)/gm
+ # Inline code: `some code here`
+ - name: inline_code
+ pattern:
+ - /`[^`\r\n]*`/g
+ - name: tf_docs
+ pattern:
+ - ^(?:\s*\|{1}\s*)(?:){1}
+ - \[.*\]\(#(?:requirement|provider|module){1}.*\)\s*
+ - \|{1}\s*\[[\w_\.]*\]\(.*\)\s*\|\s(?:resource|data source)\s*\|
+ - (?:\|\s*){1}(?:Azure\/avm){1}.*(?:\s*\|){1}
+ # Markdown link / image targets: only the `](url)` portion is ignored so
+ # typos in the visible link text or image alt text are still caught.
+ # Matches both `[text](url)` and `` because we only skip the
+ # parentheses payload.
+ - name: md_link
+ pattern:
+ - /\]\([^)]*\)/g
+ # URLs
+ - name: url
+ pattern:
+ - /https?:\/\/[^\s)>]*/g
+ # @mentions like @user or @team-name
+ - name: at_mention
+ pattern:
+ - /(?]+>/g
+ # Content between HTML ... tags (used in tables that can't use markdown code fences)
+ - name: html_code_tag
+ pattern:
+ - /[\s\S]*?<\/code>/g
+ # Email addresses
+ - name: email_address
+ pattern:
+ - /[\w.+-]+@[\w.-]+\.[a-zA-Z]{2,}/g
+ # Hugo / Docsy shortcodes: {{< rad file="..." >}} or {{% notice %}}
+ - name: hugo_shortcode
+ pattern:
+ - /\{\{[%<][\s\S]*?[%>]\}\}/g
+ # Hugo front matter: only skip non-rendered keys so user-facing fields
+ # (title, description, linkTitle) are still spell-checked. The first
+ # sub-pattern covers single-line `key: value` entries; the second covers
+ # multi-line list values (e.g. `aliases:` followed by indented `- /path`
+ # items); the third matches the `---` / `+++` delimiter lines.
+ - name: front_matter
+ pattern:
+ - /^(?:type|weight|slug|url|no_list|manualLink|manualLinkTarget|category|categories|tags)\s*:[^\n]*$/gm
+ - /^aliases\s*:[^\n]*(?:\n[ \t]+-[^\n]*)*/gm
+ - /^(?:---|\+\+\+)\s*$/gm
+
+# Use the shared .cspellignore file (at the repo root) as a custom dictionary.
+dictionaryDefinitions:
+ - name: cspellignore
+ path: ../../.cspellignore
+ addWords: true
+
+# Allow compound words to be checked as a single word
+# (e.g., "spellcheck" instead of "spell check").
+allowCompoundWords: true
+
+# Paths that should not be spell-checked: vendored theme/modules, generated
+# Hugo output, dependency folders and the shared dictionary itself.
+# Patterns use the `**/` prefix because cspell resolves ignorePaths relative
+# to the config file location (.github/linters/). Entries that do not exist in
+# a given repository are simply no-ops, so this superset is safe to share.
+ignorePaths:
+ - "**/node_modules/**"
+ - "**/.dev/**"
+ - "**/.venv/**"
+ - "**/venv/**"
+ - "**/.terraform/**"
+ - "**/.cspellignore"
+ - "**/themes/**"
+ - "**/_vendor/**"
+ - "**/public/**"
+ - "**/resources/_gen/**"
+ - "**/holding-pen/**"
+ - "**/redirect/**"
+ - "**/presentation-pack/**"
+
+# Only check markdown files (the workflow also restricts the glob to **/*.md).
+files:
+ - "**/*.md"
diff --git a/.github/linters/.markdownlint-cli2.yaml b/.github/linters/.markdownlint-cli2.yaml
new file mode 100644
index 000000000..2f24d9cab
--- /dev/null
+++ b/.github/linters/.markdownlint-cli2.yaml
@@ -0,0 +1,32 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/DavidAnson/markdownlint-cli2/main/schema/markdownlint-cli2-config-schema.json
+# ------------------------------------------------------------------------------
+# This file is synced from the radius-project/.github repository.
+# DO NOT EDIT MANUALLY - changes will be overwritten by the next sync.
+# Source: https://github.com/radius-project/.github
+# ------------------------------------------------------------------------------
+---
+config:
+ extends: ./.markdownlint.yml
+gitignore: true
+# `gitignore: true` already skips anything in .gitignore, so most build output is
+# covered. The entries below target committed/vendored content that still should
+# not be linted. Kept in sync with the ignorePaths in .cspell.yml.
+ignores:
+ - .git
+ # Dependencies, infra and build output (belt-and-suspenders with gitignore).
+ - "**/node_modules/**"
+ - "**/dist/**"
+ - "**/build/**"
+ - "**/.terraform/**"
+ - "**/venv/**"
+ - "**/.venv/**"
+ # Hugo vendored themes/modules and generated output (docs, website, blog).
+ - "**/themes/**"
+ - "**/_vendor/**"
+ - "**/public/**"
+ - "**/resources/_gen/**"
+ # Auto-generated or staged content that shouldn't be spell/lint checked.
+ - "**/CHANGELOG.md"
+ - "**/holding-pen/**"
+ - "**/redirect/**"
+ - .copilot-tracking/**
diff --git a/.github/linters/.markdownlint.yml b/.github/linters/.markdownlint.yml
new file mode 100644
index 000000000..5e6a0afbb
--- /dev/null
+++ b/.github/linters/.markdownlint.yml
@@ -0,0 +1,49 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/DavidAnson/markdownlint/refs/heads/main/schema/markdownlint-config-schema-strict.json
+# ------------------------------------------------------------------------------
+# This file is synced from the radius-project/.github repository.
+# DO NOT EDIT MANUALLY - changes will be overwritten by the next sync.
+# Source: https://github.com/radius-project/.github
+# ------------------------------------------------------------------------------
+---
+# Markdownlint YAML configuration
+# Default source: https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.yaml
+
+# Default state for all rules
+default: true
+
+# Path to configuration file to extend
+# extends: null
+
+# MD004/ul-style - Unordered list style - https://github.com/DavidAnson/markdownlint/blob/main/doc/md004.md
+MD004:
+ style: dash
+
+# MD013/line-length - Line length - https://github.com/DavidAnson/markdownlint/blob/main/doc/md013.md
+MD013: false
+
+# MD024/no-duplicate-heading - Multiple headings with the same content - https://github.com/DavidAnson/markdownlint/blob/main/doc/md024.md
+MD024: false
+
+# MD025/single-title - Single title - https://github.com/DavidAnson/markdownlint/blob/main/doc/md025.md
+MD025:
+ front_matter_title: ""
+
+# MD029/ol-prefix - Ordered list item prefix - https://github.com/DavidAnson/markdownlint/blob/main/doc/md029.md
+MD029:
+ style: one_or_ordered
+
+# MD033/no-inline-html - Inline HTML - https://github.com/DavidAnson/markdownlint/blob/main/doc/md033.md
+MD033:
+ # Allowed elements
+ allowed_elements: [br, pre]
+
+# MD036/no-emphasis-as-heading - Emphasis used instead of a heading - https://github.com/DavidAnson/markdownlint/blob/main/doc/md036.md
+MD036: false
+
+# MD041/first-line-heading/first-line-h1 - First line in file should be a top level heading - https://github.com/DavidAnson/markdownlint/blob/main/doc/md041.md
+MD041: false
+
+# MD046/code-block-style - Code block style - https://github.com/DavidAnson/markdownlint/blob/main/doc/md046.md
+MD046:
+ # Block style
+ style: fenced
diff --git a/.github/linters/.prettierrc.yml b/.github/linters/.prettierrc.yml
new file mode 100644
index 000000000..e46686d54
--- /dev/null
+++ b/.github/linters/.prettierrc.yml
@@ -0,0 +1,44 @@
+# yaml-language-server: $schema=https://www.schemastore.org/prettierrc.json
+# ------------------------------------------------------------------------------
+# This file is synced from the radius-project/.github repository.
+# DO NOT EDIT MANUALLY - changes will be overwritten by the next sync.
+# Source: https://github.com/radius-project/.github
+# ------------------------------------------------------------------------------
+---
+arrowParens: always
+bracketSpacing: true
+endOfLine: lf
+htmlWhitespaceSensitivity: css
+insertPragma: false # consider true
+singleAttributePerLine: false
+bracketSameLine: false
+jsxSingleQuote: true
+printWidth: 120
+proseWrap: preserve
+quoteProps: as-needed
+requirePragma: false # consider true
+semi: true
+singleQuote: true
+tabWidth: 2
+trailingComma: none
+useTabs: false
+vueIndentScriptAndStyle: true
+embeddedLanguageFormatting: auto
+experimentalTernaries: true
+experimentalOperatorPosition: end
+# multilineArraysWrapThreshold: 1
+# plugins:
+# - prettier-plugin-toml
+# - prettier-plugin-multiline-arrays
+
+# Language-specific overrides
+overrides:
+ - files: "*.md"
+ options:
+ proseWrap: preserve
+ - files: "*.yml"
+ options:
+ singleQuote: false
+ - files: "*.yaml"
+ options:
+ singleQuote: false
diff --git a/.github/linters/.shellcheckrc b/.github/linters/.shellcheckrc
new file mode 100644
index 000000000..7c293bc7d
--- /dev/null
+++ b/.github/linters/.shellcheckrc
@@ -0,0 +1,7 @@
+# .shellcheckrc
+# ------------------------------------------------------------------------------
+# This file is synced from the radius-project/.github repository.
+# DO NOT EDIT MANUALLY - changes will be overwritten by the next sync.
+# Source: https://github.com/radius-project/.github
+# ------------------------------------------------------------------------------
+disable=SC3037,SC2086,SC2155
diff --git a/.github/linters/.yamllint.yml b/.github/linters/.yamllint.yml
new file mode 100644
index 000000000..0df3059e2
--- /dev/null
+++ b/.github/linters/.yamllint.yml
@@ -0,0 +1,38 @@
+# yaml-language-server: $schema=https://www.schemastore.org/yamllint.json
+# docs: https://yamllint.readthedocs.io/en/stable/configuration.html#extending-the-default-configuration
+# ------------------------------------------------------------------------------
+# This file is synced from the radius-project/.github repository.
+# DO NOT EDIT MANUALLY - changes will be overwritten by the next sync.
+# Source: https://github.com/radius-project/.github
+# ------------------------------------------------------------------------------
+---
+extends: default
+
+locale: en_US.UTF-8
+
+rules:
+ document-start:
+ level: warning
+ ignore:
+ - .cspell.yml
+ line-length: disable
+ quoted-strings:
+ level: error
+ quote-type: double
+ required: only-when-needed
+ # dependabot.yml is generated by sync and quotes path values like "/"; the
+ # rule stays enabled for every other file.
+ ignore:
+ - dependabot.yml
+ comments:
+ min-spaces-from-content: 1
+ braces:
+ level: warning
+ min-spaces-inside: 0
+ max-spaces-inside: 1
+ truthy:
+ check-keys: false
+
+ignore-from-file:
+ - .gitignore
+ - .yamlignore