com.wallstop-studios.dxmessaging 2.1.5 → 2.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/.artifacts/SourceGenerators.Tests/obj/Debug/net9.0/WallstopStudios.DxMessaging.SourceGenerators.Tests.AssemblyInfo.cs +1 -1
  2. package/.cspell.json +4 -1
  3. package/.github/workflows/actionlint.yml +11 -1
  4. package/.github/workflows/csharpier-autofix.yml +34 -3
  5. package/.github/workflows/dotnet-tests.yml +13 -0
  6. package/.github/workflows/format-on-demand.yml +38 -44
  7. package/.github/workflows/json-format-check.yml +24 -0
  8. package/.github/workflows/lint-doc-links.yml +13 -0
  9. package/.github/workflows/markdown-json.yml +21 -4
  10. package/.github/workflows/markdown-link-text-check.yml +10 -0
  11. package/.github/workflows/markdown-link-validity.yml +10 -0
  12. package/.github/workflows/markdownlint.yml +7 -5
  13. package/.github/workflows/prettier-autofix.yml +67 -11
  14. package/.github/workflows/release-drafter.yml +2 -2
  15. package/.github/workflows/sync-wiki.yml +3 -3
  16. package/.github/workflows/yaml-format-lint.yml +26 -0
  17. package/.llm/context.md +113 -3
  18. package/.llm/skills/documentation/changelog-management.md +38 -0
  19. package/.llm/skills/documentation/documentation-style-guide.md +18 -0
  20. package/.llm/skills/documentation/documentation-update-workflow.md +2 -0
  21. package/.llm/skills/documentation/documentation-updates.md +2 -0
  22. package/.llm/skills/documentation/markdown-compatibility.md +476 -0
  23. package/.llm/skills/documentation/mermaid-theming.md +326 -0
  24. package/.llm/skills/documentation/mkdocs-navigation.md +290 -0
  25. package/.llm/skills/github-actions/git-renormalize-patterns.md +231 -0
  26. package/.llm/skills/github-actions/workflow-consistency.md +346 -0
  27. package/.llm/skills/index.md +53 -27
  28. package/.llm/skills/scripting/javascript-code-quality.md +417 -0
  29. package/.llm/skills/scripting/regex-documentation.md +461 -0
  30. package/.llm/skills/scripting/shell-best-practices.md +55 -4
  31. package/.llm/skills/scripting/validation-patterns.md +418 -0
  32. package/.llm/skills/specification.md +4 -1
  33. package/.llm/skills/testing/test-code-quality.md +243 -0
  34. package/.llm/skills/testing/test-production-code.md +348 -0
  35. package/CHANGELOG.md +11 -0
  36. package/README.md +0 -11
  37. package/Tests/Runtime/Benchmarks/WallstopStudios.DxMessaging.Tests.Runtime.Benchmarks.asmdef +1 -6
  38. package/Tests/Runtime/Integrations/Reflex/WallstopStudios.DxMessaging.Tests.Runtime.Reflex.asmdef +1 -1
  39. package/Tests/Runtime/Integrations/VContainer/WallstopStudios.DxMessaging.Tests.Runtime.VContainer.asmdef +1 -1
  40. package/Tests/Runtime/Integrations/Zenject/WallstopStudios.DxMessaging.Tests.Runtime.Zenject.asmdef +1 -1
  41. package/coverage/clover.xml +216 -3
  42. package/coverage/clover.xml.meta +7 -7
  43. package/coverage/coverage-final.json +2 -1
  44. package/coverage/coverage-final.json.meta +7 -7
  45. package/coverage/lcov-report/base.css.meta +1 -1
  46. package/coverage/lcov-report/block-navigation.js.meta +1 -1
  47. package/coverage/lcov-report/favicon.png.meta +1 -1
  48. package/coverage/lcov-report/index.html +25 -10
  49. package/coverage/lcov-report/index.html.meta +7 -7
  50. package/coverage/lcov-report/prettify.css.meta +1 -1
  51. package/coverage/lcov-report/prettify.js.meta +1 -1
  52. package/coverage/lcov-report/sort-arrow-sprite.png.meta +1 -1
  53. package/coverage/lcov-report/sorter.js.meta +1 -1
  54. package/coverage/lcov-report/transform-docs-to-wiki.js.html +1 -1
  55. package/coverage/lcov-report/transform-docs-to-wiki.js.html.meta +7 -7
  56. package/coverage/lcov-report/vendor.meta +1 -1
  57. package/coverage/lcov-report.meta +8 -8
  58. package/coverage/lcov.info +365 -0
  59. package/coverage/lcov.info.meta +7 -7
  60. package/docs/architecture/design-and-architecture.md +0 -1
  61. package/docs/concepts/index.md +37 -0
  62. package/docs/concepts/index.md.meta +7 -0
  63. package/docs/concepts/interceptors-and-ordering.md +0 -2
  64. package/docs/concepts/mental-model.md +390 -0
  65. package/docs/concepts/mental-model.md.meta +7 -0
  66. package/docs/concepts/message-types.md +0 -1
  67. package/docs/getting-started/getting-started.md +1 -0
  68. package/docs/getting-started/index.md +6 -5
  69. package/docs/getting-started/overview.md +1 -0
  70. package/docs/getting-started/quick-start.md +2 -1
  71. package/docs/getting-started/visual-guide.md +4 -10
  72. package/docs/hooks.py +10 -1
  73. package/docs/images/DxMessaging-banner.svg +1 -1
  74. package/docs/index.md +7 -7
  75. package/docs/javascripts/mermaid-config.js +44 -4
  76. package/docs/reference/helpers.md +130 -154
  77. package/docs/reference/quick-reference.md +5 -1
  78. package/docs/reference/reference.md +124 -130
  79. package/mkdocs.yml +2 -0
  80. package/package.json +1 -1
  81. package/scripts/__tests__/generate-skills-index.test.js +397 -0
  82. package/scripts/__tests__/generate-skills-index.test.js.meta +7 -0
  83. package/scripts/__tests__/mermaid-config.test.js +467 -0
  84. package/scripts/__tests__/mermaid-config.test.js.meta +7 -0
  85. package/scripts/__tests__/validate-skills-optional-fields.test.js +1474 -0
  86. package/scripts/__tests__/validate-skills-optional-fields.test.js.meta +7 -0
  87. package/scripts/__tests__/validate-skills-required-fields.test.js +188 -0
  88. package/scripts/__tests__/validate-skills-required-fields.test.js.meta +7 -0
  89. package/scripts/__tests__/validate-skills-tags.test.js +353 -0
  90. package/scripts/__tests__/validate-skills-tags.test.js.meta +7 -0
  91. package/scripts/__tests__/validate-workflows.test.js +188 -0
  92. package/scripts/__tests__/validate-workflows.test.js.meta +7 -0
  93. package/scripts/generate-skills-index.js +88 -3
  94. package/scripts/validate-skills.js +230 -30
  95. package/scripts/validate-workflows.js +272 -0
  96. package/scripts/validate-workflows.js.meta +7 -0
  97. package/site/404.html +1 -1
  98. package/site/advanced/emit-shorthands/index.html +2 -2
  99. package/site/advanced/message-bus-providers/index.html +2 -2
  100. package/site/advanced/registration-builders/index.html +2 -2
  101. package/site/advanced/runtime-configuration/index.html +2 -2
  102. package/site/advanced/string-messages/index.html +2 -2
  103. package/site/advanced.meta +1 -1
  104. package/site/architecture/comparisons/index.html +2 -2
  105. package/site/architecture/design-and-architecture/index.html +2 -2
  106. package/site/architecture/performance/index.html +1 -1
  107. package/site/architecture.meta +1 -1
  108. package/site/concepts/index.html +1 -0
  109. package/site/concepts/index.html.meta +7 -0
  110. package/site/concepts/interceptors-and-ordering/index.html +4 -4
  111. package/site/concepts/listening-patterns/index.html +2 -2
  112. package/site/concepts/mental-model/index.html +146 -0
  113. package/site/concepts/mental-model/index.html.meta +7 -0
  114. package/site/concepts/mental-model.meta +8 -0
  115. package/site/concepts/message-types/index.html +2 -2
  116. package/site/concepts/targeting-and-context/index.html +2 -2
  117. package/site/concepts.meta +1 -1
  118. package/site/examples/end-to-end/index.html +2 -2
  119. package/site/examples/end-to-end-scene-transitions/index.html +2 -2
  120. package/site/examples.meta +1 -1
  121. package/site/getting-started/getting-started/index.html +3 -3
  122. package/site/getting-started/index.html +4 -4
  123. package/site/getting-started/install/index.html +3 -3
  124. package/site/getting-started/overview/index.html +2 -2
  125. package/site/getting-started/quick-start/index.html +2 -2
  126. package/site/getting-started/visual-guide/index.html +11 -11
  127. package/site/getting-started.meta +1 -1
  128. package/site/guides/advanced/index.html +2 -2
  129. package/site/guides/diagnostics/index.html +2 -2
  130. package/site/guides/migration-guide/index.html +2 -2
  131. package/site/guides/patterns/index.html +2 -2
  132. package/site/guides/testing/index.html +2 -2
  133. package/site/guides/unity-integration/index.html +2 -2
  134. package/site/guides.meta +1 -1
  135. package/site/hooks.py.meta +1 -1
  136. package/site/images/DxMessaging-banner.svg +119 -0
  137. package/site/images/DxMessaging-banner.svg.meta +7 -0
  138. package/site/images.meta +8 -0
  139. package/site/index.html +2 -2
  140. package/site/integrations/index.html +2 -2
  141. package/site/integrations/reflex/index.html +2 -2
  142. package/site/integrations/vcontainer/index.html +2 -2
  143. package/site/integrations/zenject/index.html +2 -2
  144. package/site/integrations.meta +1 -1
  145. package/site/javascripts/csharp-highlight.js.meta +7 -7
  146. package/site/javascripts/mermaid-config.js +4 -1
  147. package/site/javascripts/mermaid-config.js.meta +1 -1
  148. package/site/javascripts.meta +1 -1
  149. package/site/reference/compatibility/index.html +1 -1
  150. package/site/reference/faq/index.html +1 -1
  151. package/site/reference/glossary/index.html +2 -2
  152. package/site/reference/helpers/index.html +15 -15
  153. package/site/reference/quick-reference/index.html +3 -3
  154. package/site/reference/reference/index.html +37 -37
  155. package/site/reference/troubleshooting/index.html +1 -1
  156. package/site/reference.meta +1 -1
  157. package/site/search/search_index.json +1 -1
  158. package/site/sitemap.xml +46 -38
  159. package/site/sitemap.xml.gz +0 -0
  160. package/site/stylesheets/extra.css.meta +1 -1
  161. package/site/stylesheets.meta +1 -1
@@ -2,7 +2,31 @@ name: Prettier Auto Fix
2
2
 
3
3
  on:
4
4
  pull_request:
5
+ paths:
6
+ - "**/*.md"
7
+ - "**/*.json"
8
+ - "**/*.asmdef"
9
+ - "**/*.yml"
10
+ - "**/*.yaml"
11
+ - ".github/workflows/**"
12
+ - ".prettierrc*"
13
+ - ".markdownlint*"
14
+ - "package.json"
15
+ - "package-lock.json"
16
+ - "scripts/check-eol.ps1"
5
17
  pull_request_target:
18
+ paths:
19
+ - "**/*.md"
20
+ - "**/*.json"
21
+ - "**/*.asmdef"
22
+ - "**/*.yml"
23
+ - "**/*.yaml"
24
+ - ".github/workflows/**"
25
+ - ".prettierrc*"
26
+ - ".markdownlint*"
27
+ - "package.json"
28
+ - "package-lock.json"
29
+ - "scripts/check-eol.ps1"
6
30
  workflow_dispatch:
7
31
 
8
32
  concurrency:
@@ -28,8 +52,8 @@ jobs:
28
52
  - name: Setup Node.js
29
53
  uses: actions/setup-node@v6
30
54
  with:
31
- node-version: '20'
32
- cache: 'npm'
55
+ node-version: "20"
56
+ cache: "npm"
33
57
  cache-dependency-path: package.json
34
58
 
35
59
  - name: Install dependencies
@@ -53,23 +77,40 @@ jobs:
53
77
 
54
78
  - name: Renormalize line endings
55
79
  if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }}
56
- run: git add --renormalize -- '*.md' '**/*.md' '*.markdown' '**/*.markdown' '*.json' '**/*.json' '*.asmdef' '**/*.asmdef' '*.asmref' '**/*.asmref' '*.yml' '**/*.yml' '*.yaml' '**/*.yaml'
80
+ shell: bash
81
+ run: |
82
+ # Renormalize each extension separately to avoid "pathspec did not match" failures
83
+ # when certain file types don't exist or aren't accessible in this checkout context
84
+ # yaml excluded: dotfiles (.pre-commit-config.yaml) match git ls-files but not git add globs
85
+ for ext in md json asmdef yml; do
86
+ if git ls-files "*.$ext" "**/*.$ext" | grep -q .; then
87
+ git add --renormalize -- "*.$ext" "**/*.$ext"
88
+ fi
89
+ done
57
90
 
58
91
  - name: Commit formatting changes to PR branch (Dependabot only)
59
92
  if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.user.login == 'dependabot[bot]' }}
93
+ id: auto-commit
60
94
  uses: stefanzweifel/git-auto-commit-action@v7
61
95
  with:
62
96
  commit_message: "chore(format): apply Prettier/markdownlint fixes"
63
97
  branch: ${{ github.head_ref }}
64
98
  add_options: --renormalize
99
+ # NOTE: yaml excluded - all .yaml files are dotfiles, which git add patterns don't match
65
100
  file_pattern: |
66
101
  **/*.md
67
- **/*.markdown
68
102
  **/*.json
69
103
  **/*.asmdef
70
- **/*.asmref
71
104
  **/*.yml
72
- **/*.yaml
105
+
106
+ - name: Refresh checkout after auto-commit
107
+ if: ${{ steps.auto-commit.outputs.changes_detected == 'true' }}
108
+ env:
109
+ HEAD_REF: ${{ github.head_ref }}
110
+ run: |
111
+ # Fetch the newly pushed commit and checkout to get normalized line endings in working tree
112
+ git fetch origin "$HEAD_REF"
113
+ git checkout -f FETCH_HEAD
73
114
 
74
115
  - name: Prettier check (Markdown)
75
116
  run: npm run format:md:check
@@ -104,8 +145,8 @@ jobs:
104
145
  - name: Setup Node.js
105
146
  uses: actions/setup-node@v6
106
147
  with:
107
- node-version: '20'
108
- cache: 'npm'
148
+ node-version: "20"
149
+ cache: "npm"
109
150
  cache-dependency-path: package.json
110
151
 
111
152
  - name: Install dependencies
@@ -126,7 +167,16 @@ jobs:
126
167
  run: npx --yes markdownlint-cli2@0.20.0 "**/*.md" "**/*.markdown" --fix
127
168
 
128
169
  - name: Renormalize line endings
129
- run: git add --renormalize -- '*.md' '**/*.md' '*.markdown' '**/*.markdown' '*.json' '**/*.json' '*.asmdef' '**/*.asmdef' '*.asmref' '**/*.asmref' '*.yml' '**/*.yml' '*.yaml' '**/*.yaml'
170
+ shell: bash
171
+ run: |
172
+ # Renormalize each extension separately to avoid "pathspec did not match" failures
173
+ # when certain file types don't exist or aren't accessible in this checkout context
174
+ # yaml excluded: dotfiles (.pre-commit-config.yaml) match git ls-files but not git add globs
175
+ for ext in md json asmdef yml; do
176
+ if git ls-files "*.$ext" "**/*.$ext" | grep -q .; then
177
+ git add --renormalize -- "*.$ext" "**/*.$ext"
178
+ fi
179
+ done
130
180
 
131
181
  - name: Detect changes
132
182
  id: changes
@@ -151,8 +201,14 @@ jobs:
151
201
  git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
152
202
  git checkout -B "$BRANCH"
153
203
  # Stage only files we format; avoid workflows to prevent permission issues
154
- # Use --renormalize to ensure LF line endings in git index per .gitattributes
155
- git add --renormalize -- '*.md' '**/*.md' '*.markdown' '**/*.markdown' '*.json' '**/*.json' '*.asmdef' '**/*.asmdef' '*.asmref' '**/*.asmref' '*.yml' '**/*.yml' '*.yaml' '**/*.yaml'
204
+ # Use --renormalize to ensure line endings in git index per .gitattributes
205
+ # Renormalize each extension separately to avoid "pathspec did not match" failures
206
+ # yaml excluded: dotfiles (.pre-commit-config.yaml) match git ls-files but not git add globs
207
+ for ext in md json asmdef yml; do
208
+ if git ls-files "*.$ext" "**/*.$ext" | grep -q .; then
209
+ git add --renormalize -- "*.$ext" "**/*.$ext"
210
+ fi
211
+ done
156
212
  git commit -m "chore(format): apply Prettier/markdownlint fixes for PR #${{ github.event.pull_request.number }}"
157
213
  git remote add upstream "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git"
158
214
  git fetch upstream
@@ -21,7 +21,7 @@ jobs:
21
21
  runs-on: ubuntu-latest
22
22
  steps:
23
23
  - name: Checkout
24
- uses: actions/checkout@v4
24
+ uses: actions/checkout@v6
25
25
 
26
26
  - name: Extract version from package.json
27
27
  id: version
@@ -85,7 +85,7 @@ jobs:
85
85
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
86
86
 
87
87
  - name: Update release body with changelog
88
- uses: actions/github-script@v7
88
+ uses: actions/github-script@v8
89
89
  env:
90
90
  RELEASE_ID: ${{ steps.release_drafter.outputs.id }}
91
91
  VERSION: ${{ steps.version.outputs.version }}
@@ -27,7 +27,7 @@ jobs:
27
27
  should-deploy: ${{ steps.check.outputs.should-deploy }}
28
28
  steps:
29
29
  - name: Checkout repository
30
- uses: actions/checkout@v4
30
+ uses: actions/checkout@v6
31
31
  with:
32
32
  fetch-depth: 2
33
33
 
@@ -80,7 +80,7 @@ jobs:
80
80
  runs-on: ubuntu-latest
81
81
  steps:
82
82
  - name: Checkout main repository
83
- uses: actions/checkout@v4
83
+ uses: actions/checkout@v6
84
84
  with:
85
85
  path: main
86
86
 
@@ -89,7 +89,7 @@ jobs:
89
89
  git clone "https://x-access-token:${{ github.token }}@github.com/${{ github.repository }}.wiki.git" wiki
90
90
 
91
91
  - name: Setup Node.js
92
- uses: actions/setup-node@v4
92
+ uses: actions/setup-node@v6
93
93
  with:
94
94
  node-version: '20'
95
95
 
@@ -2,19 +2,45 @@ name: YAML Format + Lint
2
2
 
3
3
  on:
4
4
  pull_request:
5
+ paths:
6
+ - "**/*.yml"
7
+ - "**/*.yaml"
8
+ - ".github/workflows/**"
9
+ - ".yamllint.yaml"
10
+ - ".prettierrc*"
11
+ - "package.json"
12
+ - "package-lock.json"
5
13
  push:
6
14
  branches:
7
15
  - main
8
16
  - master
17
+ paths:
18
+ - "**/*.yml"
19
+ - "**/*.yaml"
20
+ - ".github/workflows/**"
21
+ - ".yamllint.yaml"
22
+ - ".prettierrc*"
23
+ - "package.json"
24
+ - "package-lock.json"
9
25
  workflow_dispatch:
10
26
 
27
+ concurrency:
28
+ group: ${{ github.workflow }}-${{ github.ref }}
29
+ cancel-in-progress: true
30
+
31
+ permissions:
32
+ contents: read
33
+
11
34
  jobs:
12
35
  yaml-checks:
13
36
  name: Prettier and yamllint
14
37
  runs-on: ubuntu-latest
38
+ timeout-minutes: 5
15
39
  steps:
16
40
  - name: Checkout
17
41
  uses: actions/checkout@v6
42
+ with:
43
+ persist-credentials: false
18
44
 
19
45
  - name: Setup Node
20
46
  uses: actions/setup-node@v6
package/.llm/context.md CHANGED
@@ -14,7 +14,7 @@
14
14
  - Format: `dotnet tool restore` then `dotnet tool run csharpier format`.
15
15
  - Build generators: `dotnet build SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj`.
16
16
  - Unity tests: open a Unity 2021.3+ project that references this package, then Window > Test Runner > PlayMode. CLI example: `Unity -batchmode -nographics -quit -projectPath <your_project> -runTests -testPlatform PlayMode -testResults ./TestResults.xml`.
17
- - Actionlint: Runs in CI on PRs/pushes to validate GitHub Actions workflows. Available as a pre-push hook (requires `actionlint` installed locally).
17
+ - Actionlint: Runs in CI on PRs/pushes to validate GitHub Actions workflows. Available as a pre-push hook (requires `actionlint` installed locally). See the [Workflow Consistency skill](./skills/github-actions/workflow-consistency.md) for required workflow structure.
18
18
  - Spellcheck: Runs in CI on PRs/pushes via `cspell` to check spelling in Markdown, C#, JSON, YAML, and script files. Dictionary is maintained in [.cspell.json](../.cspell.json). Available as a pre-push hook via `npx cspell`.
19
19
 
20
20
  ## Coding Style & Naming Conventions
@@ -78,11 +78,20 @@ $extensions = @('.cs', '.csproj', '.sln', ...)
78
78
  const crlfExts = new Set(['.cs', '.csproj', '.sln', ...]);
79
79
  ```
80
80
 
81
+ ### SYNC Note Best Practices
82
+
83
+ - **Always bidirectional**: When code A has a SYNC note referencing code B, code B must also have a SYNC note referencing code A. One-way SYNC notes are easily missed during updates.
84
+ - **Never use line numbers**: Reference function names, class names, or named anchors instead. Line numbers become stale as code evolves.
85
+ - **Use descriptive identifiers**: `SYNC: Keep logic in sync with validate-skills.js validateSkill() tags validation` is better than `SYNC: Keep in sync with validate-skills.js lines 224-250`.
86
+ - **Verify references exist**: Before adding a SYNC note, confirm the referenced function, variable, or block actually exists with the exact name.
87
+
81
88
  ### Shell Pattern Matching
82
89
 
83
90
  - Use `grep -F` for literal string matching (paths, filenames with special characters like `.`).
84
91
  - Use `grep -E` only when regex features are explicitly needed.
85
92
  - Remember that `.` in a regex matches any character, not just a literal dot.
93
+ - **Count escape sequences carefully**: Each `\.` matches exactly one literal dot. The pattern `^\.\.$` matches the literal string `..` (two consecutive dots), not "any string with dots at each end."
94
+ - **Dotfile matching**: To match dotfiles (files starting with `.`), use `^\.` which is sufficient for `git ls-files` output since `..` directory entries are never listed.
86
95
  - Always quote variable expansions in patterns: `grep -F "$PATH_VAR/"` not `grep -F $PATH_VAR/`.
87
96
  - **`grep` exit codes**: `grep` returns exit code 1 when no matches are found, which fails CI pipelines. Use `|| true`, `|| echo "0"`, or pipe to `wc -l` instead of `grep -c` when zero matches is acceptable.
88
97
 
@@ -99,10 +108,14 @@ This project uses CRLF for most files but LF for shell scripts (`.sh`, `.bash`,
99
108
  - **Prefer `fix-eol.js` for working tree fixes**: Run `node scripts/fix-eol.js` to directly fix line endings in your working tree. This is the recommended approach after cloning or when files have incorrect endings.
100
109
  - **`git add --renormalize` only updates the index**: This command updates the git staging area based on `.gitattributes` but does **not** modify working tree files. Use it only when you need to re-stage files with updated normalization rules.
101
110
  - **`git add --renormalize` must target specific paths**: Never use `git add --renormalize .` as it stages all files. Always specify exact patterns like `git add --renormalize -- '*.md' '**/*.md'`.
111
+ - **Use per-extension loops for `git add --renormalize`**: Multi-pattern renormalize commands fail with exit code 128 if any pattern matches no files. Use a loop to process each extension separately with existence checks. Example: `for ext in md json yml; do if git ls-files "*.$ext" "**/*.$ext" | grep -q .; then git add --renormalize -- "*.$ext" "**/*.$ext"; fi; done`.
112
+ - **Dotfiles do not match glob patterns in `git add`**: The command `git ls-files "*.yaml"` matches dotfiles like `.pre-commit-config.yaml`, but `git add --renormalize -- "*.yaml"` does NOT match dotfiles. This causes the existence check to pass but the renormalize to fail. Exclude `yaml` from extension loops since the only `.yaml` files are typically dotfiles; use `yml` instead.
113
+ - **Generalized rule for dotfile-only extensions**: Exclude any extension from `git add --renormalize` loops when ALL tracked files of that extension are dotfiles (files whose names start with `.`). To check: run `git ls-files "*.$ext" "**/*.$ext"` and verify whether any results are non-dotfiles. If all matches are dotfiles, exclude that extension.
102
114
  - **Error messages must be specific**: Indicate which policy was violated (e.g., "Expected LF for shell scripts" vs "Expected CRLF per project policy").
103
115
  - **git-auto-commit-action `file_pattern`**: This only limits what gets newly added; previously staged files still get committed. Ensure preceding `git add` commands target the same file set.
116
+ - **`file_pattern` does not match dotfiles**: Like `git add`, the `file_pattern` option in `git-auto-commit-action` uses glob patterns that do not match dotfiles. Exclude patterns like `**/*.yaml` from `file_pattern` when all `.yaml` files are dotfiles (e.g., `.pre-commit-config.yaml`). This follows the same rule as excluding `yaml` from `git add --renormalize` loops.
104
117
 
105
- See the [Git Workflow Robustness skill](./skills/testing/git-workflow-robustness.md) for detailed patterns.
118
+ See the [Git Workflow Robustness skill](./skills/testing/git-workflow-robustness.md) and the [Git Renormalize Patterns skill](./skills/github-actions/git-renormalize-patterns.md) for detailed patterns.
106
119
 
107
120
  ### Forbidden Commands
108
121
 
@@ -116,6 +129,83 @@ See the [Git Workflow Robustness skill](./skills/testing/git-workflow-robustness
116
129
  - Prefer `const` over `let`; use `let` only when reassignment is necessary.
117
130
  - When adding validation constants (e.g., `VALID_X`), ensure corresponding validation logic uses them.
118
131
 
132
+ #### Presence vs Value Validation
133
+
134
+ When validating input, clearly separate "presence" checks (is the value defined?) from "value" checks (is the defined value valid?). This two-phase approach produces clearer error messages and more maintainable code.
135
+
136
+ ##### Checking for missing values (undefined/null)
137
+
138
+ ```javascript
139
+ // CORRECT: Explicit null/undefined check
140
+ if (frontmatter[field] === undefined || frontmatter[field] === null) {
141
+ errors.push(`Required field '${field}' is missing`);
142
+ }
143
+
144
+ // ALSO CORRECT: Loose equality shorthand (null == undefined is true)
145
+ if (frontmatter[field] == null) {
146
+ errors.push(`Required field '${field}' is missing`);
147
+ }
148
+
149
+ // WRONG: Falsy check conflates missing with empty/invalid
150
+ if (!frontmatter[field]) {
151
+ errors.push(`Required field '${field}' is missing`); // Misleading: also triggers for ""
152
+ }
153
+ ```
154
+
155
+ ###### Two-phase validation pattern
156
+
157
+ ```javascript
158
+ // Phase 1: Check presence
159
+ if (value === undefined || value === null) {
160
+ errors.push("Value is missing");
161
+ } else if (value === "") {
162
+ // Phase 2: Check value validity (only if present)
163
+ errors.push("Value is empty");
164
+ } else if (!isValidFormat(value)) {
165
+ errors.push("Value has invalid format");
166
+ }
167
+ ```
168
+
169
+ ###### When to use falsy checks (`!x`)
170
+
171
+ - Only when you explicitly want to catch ALL falsy values: `undefined`, `null`, `0`, `""`, `false`, `NaN`
172
+ - Common legitimate uses: `if (!array.length)` to check empty arrays, `if (!str.trim())` to check whitespace-only strings
173
+
174
+ ###### Common pitfalls
175
+
176
+ - **Empty array is truthy**: `[]` is truthy, so `![]` is `false`. Use `!array.length` instead.
177
+ - **Zero is falsy**: `0` is falsy, so `!count` fails when count is legitimately zero.
178
+ - **Empty string vs missing**: `!value` treats `""` the same as `undefined`, but they often need different error messages.
179
+
180
+ ###### Guard clause for enum validation
181
+
182
+ When checking if a value is valid according to an enum/allowlist, guard against missing and empty values first. This prevents spurious "invalid value" errors for empty strings:
183
+
184
+ ```javascript
185
+ // CORRECT: Guard against missing and empty before enum check
186
+ if (value != null && value !== "" && !VALID_VALUES.includes(value)) {
187
+ errors.push(`Invalid ${fieldName}: '${value}'`);
188
+ }
189
+
190
+ // WRONG: Missing guard allows empty string to be flagged as "invalid"
191
+ if (!VALID_VALUES.includes(value)) {
192
+ errors.push(`Invalid ${fieldName}: '${value}'`); // Reports "" as "Invalid: ''"
193
+ }
194
+ ```
195
+
196
+ ###### Type coercion for YAML values
197
+
198
+ YAML parsers may return non-string types (e.g., `1.0.0` becomes number `1`). Use `String()` after presence checks:
199
+
200
+ ```javascript
201
+ if (value != null && value !== "") {
202
+ const strValue = String(value);
203
+ if (!strValue.match(/^\d+\.\d+\.\d+$/)) {
204
+ errors.push(`Invalid format: '${strValue}'`);
205
+ }
206
+ }
207
+ ```
208
+
119
209
  ### Jest Test Style
120
210
 
121
211
  For JavaScript tests using Jest:
@@ -123,6 +213,9 @@ For JavaScript tests using Jest:
123
213
  - **Use `test()` not `it()`**: All tests must use `test()` for consistency with existing tests.
124
214
  - **Descriptive names**: Test descriptions should clearly state what is being tested.
125
215
  - **Group with `describe()`**: Use `describe()` blocks to group related tests logically.
216
+ - **Accurate categorization**: `describe()` block names must accurately reflect the tests they contain. Do not group "undefined/null" checks under "falsy" if falsy wrong-type values (empty string, 0, false) are tested separately.
217
+ - **Test accuracy**: Test names, descriptions, and comments must be factually correct. Never include statements that contradict how JavaScript actually behaves (e.g., claiming "empty array is falsy" when it is truthy).
218
+ - **Message content tests**: When code produces user-facing messages, add tests that verify message content matches actual UI/output terminology.
126
219
 
127
220
  ```javascript
128
221
  // CORRECT
@@ -197,6 +290,17 @@ This project maintains a strict **zero-flaky test policy**. Every test failure i
197
290
 
198
291
  See the [Test Failure Investigation skill](./skills/testing/test-failure-investigation.md) for detailed investigation patterns and procedures.
199
292
 
293
+ ### Test Production Code Directly
294
+
295
+ Tests must import and exercise actual production code, never re-implement production logic locally. Re-implementing validation or business logic in tests creates a false sense of security - tests can pass while production code regresses.
296
+
297
+ - **Import production functions**: Tests should import and call the actual production functions, not local copies.
298
+ - **Export testable helpers**: Structure production code with exported helper functions that tests can verify.
299
+ - **Avoid duplication**: If test files contain utility functions that mirror production logic, refactor to import instead.
300
+ - **Use SYNC notes for unavoidable duplication**: When parallel implementations are necessary (e.g., PowerShell scripts tested via JavaScript), use bidirectional SYNC notes referencing function names.
301
+
302
+ See the [Test Production Code skill](./skills/testing/test-production-code.md) for patterns and examples.
303
+
200
304
  ## Documentation Guidelines
201
305
 
202
306
  After any new feature or bug fix, documentation must be updated:
@@ -206,20 +310,24 @@ After any new feature or bug fix, documentation must be updated:
206
310
  - **XML docs**: Update `<summary>`, `<param>`, `<returns>`, and `<remarks>` for public APIs.
207
311
  - **Code samples**: Ensure examples are correct, compilable, and tested.
208
312
  - **README**: Update [the README](../README.md) for significant features or breaking changes.
313
+ - **MkDocs navigation**: When adding new pages to `docs/`, always add corresponding entries to `mkdocs.yml` nav section.
209
314
 
210
315
  When documenting new behavior, note the version it was introduced (e.g., "Added in v1.2.0").
211
316
 
212
- See the [Documentation Updates skill](./skills/documentation/documentation-updates.md) and [Changelog Management skill](./skills/documentation/changelog-management.md) for detailed guidance.
317
+ See the [Documentation Updates skill](./skills/documentation/documentation-updates.md), [Changelog Management skill](./skills/documentation/changelog-management.md), and [MkDocs Navigation skill](./skills/documentation/mkdocs-navigation.md) for detailed guidance.
213
318
 
214
319
  ### Markdown Formatting Conventions
215
320
 
216
321
  - **Ordered lists**: Use lazy numbering (`1.`, `1.`, `1.`) not sequential (`1.`, `2.`, `3.`). This matches Prettier behavior and markdownlint MD029 configuration.
217
322
  - **Fenced code blocks**: Use triple backticks (```), not indented blocks.
323
+ - **Nested fences**: When showing code blocks inside code blocks (e.g., documenting markdown), the outer fence must have MORE backticks than inner fences. Use ``for outer when inner uses` ```.
218
324
  - **Line endings**: CRLF, no UTF-8 BOM (enforced by pre-commit hooks).
219
325
  - **Headings**: Use ATX-style headings (`#`, `##`, `###`) not underlined style.
220
326
  - **Line length**: Not enforced. Write naturally; let lines wrap as needed.
221
327
  - **Inline code spacing**: Always include a space before and after inline code when adjacent to text. Write ``the `code` here`` not ``the`code`here``. This improves readability and matches CommonMark best practices.
222
328
 
329
+ See the [Markdown Compatibility skill](./skills/documentation/markdown-compatibility.md) for MkDocs-specific syntax to avoid.
330
+
223
331
  ## Changelog Guidelines
224
332
 
225
333
  Every user-facing change must be added to [the changelog](../CHANGELOG.md):
@@ -229,6 +337,8 @@ Every user-facing change must be added to [the changelog](../CHANGELOG.md):
229
337
  - Include proper version headers with dates (e.g., `## [1.2.0] - 2026-01-22`).
230
338
  - Link issues and PRs in entries (e.g., "Fixed registration bug (#123)").
231
339
  - Write entries from the user's perspective, focusing on impact.
340
+ - Entries must describe **user-visible** changes only; do not document internal tooling, AI agent guidance, or developer-only changes like `.llm/` skill files.
341
+ - Use accurate scope: if only some files/assemblies were changed, name them specifically rather than implying all were changed.
232
342
 
233
343
  See the [Changelog Management skill](./skills/documentation/changelog-management.md) for detailed guidance.
234
344
 
@@ -171,6 +171,44 @@ MAJOR.MINOR.PATCH
171
171
  - Link issues or PRs when available
172
172
  - Flag breaking changes explicitly with migration guidance
173
173
 
174
+ ## Anti-Patterns
175
+
176
+ ### Anti-Pattern 1: Internal Tooling or AI Agent Documentation
177
+
178
+ ```markdown
179
+ <!-- WRONG -->
180
+
181
+ ### Added
182
+
183
+ - MkDocs navigation skill documenting navigation patterns
184
+ ```
185
+
186
+ Changelog entries describe changes that **users experience**, not internal tooling, AI agent guidance, or developer-facing documentation. Skills, context files, and internal process documentation are invisible to package consumers and do not belong in the changelog.
187
+
188
+ **What to document instead**: Changes to user-facing documentation (API docs, tutorials, README) may warrant changelog entries if they significantly improve the user experience.
189
+
190
+ ### Anti-Pattern 2: Overly Broad Scope
191
+
192
+ ```markdown
193
+ <!-- WRONG -->
194
+
195
+ ### Changed
196
+
197
+ - Updated test assembly definitions
198
+ ```
199
+
200
+ This entry implies all test assembly definitions were changed, which is rarely accurate. Entries must accurately scope what was actually affected.
201
+
202
+ ```markdown
203
+ <!-- CORRECT -->
204
+
205
+ ### Fixed
206
+
207
+ - `WallstopStudios.DxMessaging.Tests.Runtime` assembly definition now specifies Editor-only platform to prevent Burst compilation errors during player builds
208
+ ```
209
+
210
+ **Rule**: Be specific about what changed. Name the exact files, assemblies, or components that were modified. Vague entries create confusion about which components were affected and make it harder to trace issues back to specific changes.
211
+
174
212
  ## See Also
175
213
 
176
214
  - [Changelog Entry Writing](changelog-entry-writing.md)
@@ -131,6 +131,24 @@ MessageRegistrationHandle handle = _messageRegistrationToken.RegisterGameObjectT
131
131
  ```
132
132
  ````
133
133
 
134
+ ### Use Correct Brand Capitalization
135
+
136
+ Technology brands have specific capitalization. Using incorrect forms looks unprofessional:
137
+
138
+ | Correct | Incorrect |
139
+ | ------------- | --------------------------- |
140
+ | GitHub | Github, github |
141
+ | JavaScript | Javascript, java script |
142
+ | TypeScript | Typescript, typescript |
143
+ | Node.js | NodeJS, Nodejs, node.js |
144
+ | npm | NPM, Npm (always lowercase) |
145
+ | C# | c#, CSharp |
146
+ | .NET | .Net, dotnet (in prose) |
147
+ | Unity | unity (in prose) |
148
+ | NuGet | Nuget, nuget |
149
+ | Visual Studio | VisualStudio |
150
+ | VS Code | VSCode, vscode (in prose) |
151
+
134
152
  ## Anti-Patterns
135
153
 
136
154
  ### Bad: Placeholder Documentation
@@ -60,6 +60,7 @@ related:
60
60
  - "documentation-xml-docs"
61
61
  - "documentation-code-samples"
62
62
  - "changelog-management"
63
+ - "mkdocs-navigation"
63
64
 
64
65
  status: "stable"
65
66
  ---
@@ -133,6 +134,7 @@ Documentation updates needed:
133
134
  - [Documentation Updates](documentation-updates.md)
134
135
  - [XML Documentation Standards](documentation-xml-docs.md)
135
136
  - [Documentation Code Samples](documentation-code-samples.md)
137
+ - [MkDocs Navigation](mkdocs-navigation.md)
136
138
  - [Changelog Management](changelog-management.md)
137
139
 
138
140
  ## References
@@ -69,6 +69,7 @@ related:
69
69
  - "documentation-code-samples"
70
70
  - "documentation-style-guide"
71
71
  - "documentation-update-workflow"
72
+ - "mkdocs-navigation"
72
73
  - "test-failure-investigation"
73
74
 
74
75
  status: "stable"
@@ -132,6 +133,7 @@ Outdated documentation misleads users and increases support load.
132
133
  - [Code Sample Requirements](documentation-code-samples.md)
133
134
  - [Documentation Style Guide](documentation-style-guide.md)
134
135
  - [Documentation Update Workflow](documentation-update-workflow.md)
136
+ - [MkDocs Navigation](mkdocs-navigation.md)
135
137
  - [Changelog Management](changelog-management.md)
136
138
 
137
139
  ## References