Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

[*]
charset = utf-8-bom
end_of_line = crlf
end_of_line = lf
trim_trailing_whitespace = false
insert_final_newline = false
indent_style = space
Expand Down
7 changes: 5 additions & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
# LF is the one canonical line ending: it is what this repository stores and
# what .editorconfig asks editors and CSharpier to write. Pinning eol keeps the
# checkout ending on every platform, so `csharpier -- check` and the pre-commit
# hook agree with git instead of only working on Windows.
###############################################################################
* text=auto
* text=auto eol=lf

###############################################################################
# Shell scripts must stay LF so shebangs and bash parsing survive Windows
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/llm-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ on:
- ".github/copilot-instructions.md"
- ".github/workflows/llm-lint.yml"
- ".pre-commit-config.yaml"
- ".editorconfig"
- ".gitattributes"
- ".devcontainer/**"
- "Editor/**/*.cs"
- "Runtime/**/*.cs"
Expand All @@ -40,6 +42,8 @@ on:
- ".github/copilot-instructions.md"
- ".github/workflows/llm-lint.yml"
- ".pre-commit-config.yaml"
- ".editorconfig"
- ".gitattributes"
- ".devcontainer/**"
- "Editor/**/*.cs"
- "Runtime/**/*.cs"
Expand Down Expand Up @@ -88,6 +92,9 @@ jobs:
- name: Enforce the release credential contract
run: node scripts/lint-release-secrets.js --verbose

- name: Enforce the line-ending contract
run: node scripts/lint-line-endings.js --verbose

- name: Enforce assembly warning policy
run: pwsh -NoProfile -File scripts/lint-assembly-warnings.ps1

Expand Down
1 change: 1 addition & 0 deletions .llm/references/forbidden-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ Patterns that must not appear in this codebase, with the compliant alternative.
| `Assert.IsNull` / `Assert.IsNotNull`, `Is.Null` / `Is.Not.Null` constraints on any value, `?.`, `??`, or implicit bool tests on `UnityEngine.Object` | `Assert.That(value == null)` / `Assert.That(value != null)`; explicit `== null` / `!= null` comparisons | Unity overloads the equality operators so a destroyed-object wrapper compares null; NUnit's IsNull, Is.Null constraints, and C#'s `?.`/`??`/bool forms use reference equality and cannot see that lifetime (`scripts/lint-csharp-null-assertions.js` enforces the assertion and constraint forms) |
| Static mutable state with no documented reason or teardown reset | document why it is static, weak-key by lifecycle owner, unregister on every removal path, and reset it in the owning window's `Cleanup()` (`AssetGuidTypeIndex.Shared` suspension reset and the theme-selection ownership registry are the precedents) | static editor state outlives windows and strands cross-window state (PR #122 review finding) |
| `using` directives above the `namespace` declaration | place them inside the namespace block; file-level usings are sanctioned only for namespaceless assembly-attribute files and `[assembly: ...]` preambles like `InternalsVisibleTo` (`npm run lint:csharp-usings` enforces this, `:fix` moves the simple cases) | one namespace-scoped convention keeps the file header stable and the rule mechanically checkable (#124) |
| A guard that reads a machine-readable config resolves only part of a construct, such as the first `{a,b}` alternative, a nested group, or one level of a nested mapping | resolve every alternative and nesting level, or refuse the pattern with the file and line that uses it | a partially-read rule still matches its own representative path, so the guard passes while the real configuration disagrees; refusing beats guessing (PR #131 review finding in `scripts/lint-line-endings.js`) |
5 changes: 5 additions & 0 deletions .llm/skills/manage-skills/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ metadata:
domain-specific how-to.
- Optional spec keys (`license`, `compatibility`, `allowed-tools`, `metadata.*`) are
tolerated but rarely needed.
- Tolerance has no teeth: an unrecognized key is ignored rather than rejected. A
misspelled `metadata.category`, or `category` written at the top level instead of
under `metadata`, silently falls back to `Feature`, so the skill is filed under the
wrong heading in the generated index with a passing lint. Check the category in
`.llm/skills/index.md` after regenerating.

## Body Contract

Expand Down
7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ repos:
pass_filenames: false
files: ^(\.llm/references/RELEASING\.md|\.github/workflows/(release-prep|release-tag|npm-publish)\.yml)$
description: Fails when a release workflow reads an undocumented secret, or a documented secret is read by no release workflow.
- id: lint-line-endings
name: Enforce the line-ending contract
entry: node scripts/lint-line-endings.js
language: system
pass_filenames: false
files: ^(\.editorconfig|\.gitattributes)$
description: Fails when .editorconfig and .gitattributes disagree about the line ending CSharpier writes and git checks out.
- id: lint-assembly-warnings
name: Enforce assembly warning policy
entry: pwsh -NoProfile -File scripts/lint-assembly-warnings.ps1
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"lint:csharp-usings": "node scripts/lint-csharp-usings.js",
"lint:csharp-usings:fix": "node scripts/lint-csharp-usings.js --fix",
"lint:release-secrets": "node scripts/lint-release-secrets.js",
"lint:llm:full": "pwsh -NoProfile -File scripts/generate-skills-index.ps1 && pwsh -NoProfile -File scripts/lint-llm-instructions.ps1 -VerboseOutput && pwsh -NoProfile -File scripts/lint-file-lengths.ps1 -VerboseOutput && node scripts/lint-csharp-member-order.js --verbose && node scripts/lint-release-secrets.js --verbose && pwsh -NoProfile -File scripts/tests/run-all.ps1",
"lint:line-endings": "node scripts/lint-line-endings.js",
"lint:llm:full": "pwsh -NoProfile -File scripts/generate-skills-index.ps1 && pwsh -NoProfile -File scripts/lint-llm-instructions.ps1 -VerboseOutput && pwsh -NoProfile -File scripts/lint-file-lengths.ps1 -VerboseOutput && node scripts/lint-csharp-member-order.js --verbose && node scripts/lint-release-secrets.js --verbose && node scripts/lint-line-endings.js --verbose && pwsh -NoProfile -File scripts/tests/run-all.ps1",
"mcp:sync": "bash .llm/mcp/sync-mcp.sh",
"unity:mcp:host": "node .llm/mcp/unity-mcp-host.mjs",
"tools:install": "bash .devcontainer/install-npm-tools.sh",
Expand Down
Loading
Loading