drywetmidi
Copilot instructions710 starsChanged 12 days agoMITView on GitHub
DryWetMIDI code style ==================== Use this file as the single source of repository coding rules for all Copilot pull requests and contributions. Read the surrounding code before editing; preserve existing public API behavior and naming. Layout ------ Use four spaces for C# indentation and put opening braces on separate lines. Keep the existing namespace, using-directive, and region conventions. Separate logical steps with blank lines. In particular: - Put a blank line after an if/else body before the next independent statement.…
We split this copilot-instructions.md into the rules it gives an agent
34 rules. About 3 are common, 30 are distinctive, and 1 is very specific to this project.
≈3
Common · estimate
Many files like this have a rule of this kind.
≈30
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 4
Use this file as the single source of repository coding rules for all Copilot pull requests and contributions.
- Distinctive: line 10
Use four spaces for C# indentation and put opening braces on separate lines.
- Distinctive: line 11
Keep the existing namespace, using-directive, and region conventions.
- Distinctive: line 14
Put a blank line after an if/else body before the next independent statement.
- Distinctive: line 15
Put blank lines before and after loops, except at a containing block boundary.
- Distinctive: line 16
Keep related declarations together, but separate setup, validation, processing, and return/completion steps.
- Distinctive: line 19
Do not insert blank lines between an if body and its else, or between a try body and its catch/finally.
- Distinctive: line 22
Always put loop bodies in braces, including single-statement bodies.
- Distinctive: line 23
Follow surrounding code for single-statement if bodies.
- Distinctive: line 26
Put blank lines between properties, methods, and constructors.
- Distinctive: line 31
Do not put catch bodies or multiple independent statements on the same line.
- Distinctive: line 33
Keep other short expression-bodied members when they are genuinely easier to read.
- Distinctive: line 35
When a declaration or invocation is split into a multiline parameter/argument list, put each parameter/argument on its own line.
- Distinctive: line 40
Avoid densely packed object initializers and chained operations.
- Distinctive: line 44
Use descriptive identifiers that name the object or value, not shortened or decorative names.
- Distinctive: line 47
Do not use magic constants for operation states or other domain-specific values.
- Distinctive: line 48
Use enums or named constants that explain their meaning.
- Common: line 52
Use ThrowIfArgument at public API boundaries, not in private or internal helpers.
- Distinctive: line 59
Keep synchronous APIs compatible.
- Distinctive: line 60
Add async APIs for genuinely awaitable I/O, not solely to wrap CPU-bound operations in Task.Run.
- Distinctive: line 62
Use ConfigureAwait(false) for internal library awaits that do not require a caller synchronization context, including asynchronous disposal …
- Distinctive: line 65
Do not remove ConfigureAwait(false) merely because a particular test uses no synchronization context.
- Distinctive: line 68
Keep cancellation cooperative.
- Distinctive: line 70
Do not refactor duplicated sync/async algorithms as part of a style-only change.
- Distinctive: line 74
Use multiline summary comments, matching existing public APIs.
- Distinctive: line 79
When adding a local async summary alongside inheritdoc, scope inheritance to exclude the inherited summary so DocFX preserves the …
- Common: line 81
Use OperationCanceledException for cancellation contracts.
- Common: line 83
Document actual exceptions rather than adding every exception to every method.
- Distinctive: line 102
Keep existing synchronous assertions and dedicated asynchronous tests.
- Distinctive: line 108
Prefer extending existing common assertion helpers so all their cases gain async coverage.
- Distinctive: line 113
Prefer NUnit Values for independent parameter values.
- Distinctive: line 116
Use MidiAsserts for MIDI equality instead of manual comparisons or calling Equals, except when Equals itself is the behavior under test.
- Distinctive: line 121
Always open pull requests as drafts.
- Very specific: line 123
If a pull request or issue from another (foreign) project is reviewed and that leads to a pull request in DryWetMIDI, do not mention the …
≈ “Common” is an estimate: at least 1 in 5 of the 3,669 Copilot instructions files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
DryWetMIDI code style
Use this file as the single source of repository coding rules for all Copilot pull requests and contributions. Read the surrounding code before editing; preserve existing public API behavior and naming.
Layout
Use four spaces for C# indentation and put opening braces on separate lines. Keep the existing namespace, using-directive, and region conventions.
Separate logical steps with blank lines. In particular:
- Put a blank line after an if/else body before the next independent statement.
- Put blank lines before and after loops, except at a containing block boundary.
- Keep related declarations together, but separate setup, validation, processing, and return/completion steps.
- In tests, separate setup, action, and verification blocks with blank lines.
- Do not insert blank lines between an if body and its else, or between a try body and its catch/finally.
Always put loop bodies in braces, including single-statement bodies. Follow surrounding code for single-statement if bodies; braces are not required just because a loop's braces are required.
Put blank lines between properties, methods, and constructors. Always place nested classes at the top of their parent class, before other members. Always put private methods after public methods; put public members before internal and private implementation helpers.
Do not put catch bodies or multiple independent statements on the same line. Constructor bodies must be multiline blocks, never expression-bodied. Keep other short expression-bodied members when they are genuinely easier to read.
When a declaration or invocation is split into a multiline parameter/argument list, put each parameter/argument on its own line. Do not leave most parameters on one line with only the final parameter on the following line.
Expand lambdas with several statements into readable multiline blocks. Avoid densely packed object initializers and chained operations.
Identifiers
Use descriptive identifiers that name the object or value, not shortened or decorative names. For example, use expectedFile and synchronousTokensReader instead of expected and synchronous. Do not use magic constants for operation states or other domain-specific values. Use enums or named constants that explain their meaning.
Argument validation
Use ThrowIfArgument at public API boundaries, not in private or internal helpers. Validate each public entry point before passing arguments to unchecked helpers, using the public parameter names in exceptions. Do not remove validation without moving it to the callers that own the public contract.
Async code
Keep synchronous APIs compatible. Name asynchronous counterparts with Async. Add async APIs for genuinely awaitable I/O, not solely to wrap CPU-bound operations in Task.Run. Leave CPU offloading to the caller. Use ConfigureAwait(false) for internal library awaits that do not require a caller synchronization context, including asynchronous disposal where applicable. It is not necessary to add an await solely to a method that returns a task. Do not remove ConfigureAwait(false) merely because a particular test uses no synchronization context.
Keep cancellation cooperative. Check it while preparing a mutation, not halfway through a destructive commit. Async does not make mutable objects thread-safe. Do not refactor duplicated sync/async algorithms as part of a style-only change.
XML documentation
Use multiline summary comments, matching existing public APIs. Document parameters, return values, ownership, and relevant exception conditions. Reuse the corresponding synchronous API's documentation when appropriate, but also document async-specific cancellation, disposed-object, overlapping-operation, and state failures when the implementation can actually produce them. When adding a local async summary alongside inheritdoc, scope inheritance to exclude the inherited summary so DocFX preserves the async-specific description. Use OperationCanceledException for cancellation contracts; do not promise the more specific TaskCanceledException for every canceled operation. Document actual exceptions rather than adding every exception to every method.
In documentation articles, link methods with xref and their fully qualified
method identifier; include the parameter signature to select an overload, or
use the method's overload-group identifier ending in * when intended.
Decorate code-related text with backticks, including API link labels:
MidiFile.ReadAsync
End text introducing a code sample with a colon, not a period.
Distinguish bulk async APIs, which complete an entire operation before returning
the result, from lazy async APIs, which perform work as items or tokens are
requested. Do not imply that asynchronous I/O alone makes a bulk API lazy.
Validate documentation with docfx 2.78.0 using: docfx Docs/docfx.json Inspect diagnostics for unresolved xrefs and other warnings, and inspect the rendered HTML for working links, readable examples, and correct API descriptions.
Tests
Keep existing synchronous assertions and dedicated asynchronous tests. For parity checks in existing synchronous tests, also exercise the asynchronous operation using CancellationToken.None and Result or Wait. Recreate mutable inputs and streams so both operations start from equivalent state. Remember that Result and Wait wrap task failures in AggregateException; preserve the original synchronous exception assertions. Prefer extending existing common assertion helpers so all their cases gain async coverage. Verify output, state changes, settings, and failure behavior, not just task completion. Do not add async calls for APIs without an async counterpart.
Prefer NUnit Values for independent parameter values; use TestCase when values are correlated cases that must stay together. Use ClassicAssert when an equivalent assertion exists. Give every assertion an informative failure message. Use MidiAsserts for MIDI equality instead of manual comparisons or calling Equals, except when Equals itself is the behavior under test.
Pull requests
Always open pull requests as drafts.
If a pull request or issue from another (foreign) project is reviewed and that leads to a pull request in DryWetMIDI, do not mention the foreign issue or pull request in the DryWetMIDI pull request description, so that no link is created between DryWetMIDI and the other project.
Where files are headingNew Copilot instructions files have more rules about branches and pull requests, and fewer about code style.
Of the Copilot instructions files we read, the 2,297 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

