agentleFS
melanchallmelanchall/drywetmidi/.github/copilot-instructions.md

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
  1. Distinctive:

    Use this file as the single source of repository coding rules for all Copilot pull requests and contributions.

    line 4
  2. Distinctive:

    Use four spaces for C# indentation and put opening braces on separate lines.

    line 10
  3. Distinctive:

    Keep the existing namespace, using-directive, and region conventions.

    line 11
  4. Distinctive:

    Put a blank line after an if/else body before the next independent statement.

    line 14
  5. Distinctive:

    Put blank lines before and after loops, except at a containing block boundary.

    line 15
  6. Distinctive:

    Keep related declarations together, but separate setup, validation, processing, and return/completion steps.

    line 16
  7. Distinctive:

    Do not insert blank lines between an if body and its else, or between a try body and its catch/finally.

    line 19
  8. Distinctive:

    Always put loop bodies in braces, including single-statement bodies.

    line 22
  9. Distinctive:

    Follow surrounding code for single-statement if bodies.

    line 23
  10. Distinctive:

    Put blank lines between properties, methods, and constructors.

    line 26
  11. Distinctive:

    Do not put catch bodies or multiple independent statements on the same line.

    line 31
  12. Distinctive:

    Keep other short expression-bodied members when they are genuinely easier to read.

    line 33
  13. Distinctive:

    When a declaration or invocation is split into a multiline parameter/argument list, put each parameter/argument on its own line.

    line 35
  14. Distinctive:

    Avoid densely packed object initializers and chained operations.

    line 40
  15. Distinctive:

    Use descriptive identifiers that name the object or value, not shortened or decorative names.

    line 44
  16. Distinctive:

    Do not use magic constants for operation states or other domain-specific values.

    line 47
  17. Distinctive:

    Use enums or named constants that explain their meaning.

    line 48
  18. Common:

    Use ThrowIfArgument at public API boundaries, not in private or internal helpers.

    line 52
  19. Distinctive:

    Keep synchronous APIs compatible.

    line 59
  20. Distinctive:

    Add async APIs for genuinely awaitable I/O, not solely to wrap CPU-bound operations in Task.Run.

    line 60
  21. Distinctive:

    Use ConfigureAwait(false) for internal library awaits that do not require a caller synchronization context, including asynchronous disposal …

    line 62
  22. Distinctive:

    Do not remove ConfigureAwait(false) merely because a particular test uses no synchronization context.

    line 65
  23. Distinctive:

    Keep cancellation cooperative.

    line 68
  24. Distinctive:

    Do not refactor duplicated sync/async algorithms as part of a style-only change.

    line 70
  25. Distinctive:

    Use multiline summary comments, matching existing public APIs.

    line 74
  26. Distinctive:

    When adding a local async summary alongside inheritdoc, scope inheritance to exclude the inherited summary so DocFX preserves the …

    line 79
  27. Common:

    Use OperationCanceledException for cancellation contracts.

    line 81
  28. Common:

    Document actual exceptions rather than adding every exception to every method.

    line 83
  29. Distinctive:

    Keep existing synchronous assertions and dedicated asynchronous tests.

    line 102
  30. Distinctive:

    Prefer extending existing common assertion helpers so all their cases gain async coverage.

    line 108
  31. Distinctive:

    Prefer NUnit Values for independent parameter values.

    line 113
  32. Distinctive:

    Use MidiAsserts for MIDI equality instead of manual comparisons or calling Equals, except when Equals itself is the behavior under test.

    line 116
  33. Distinctive:

    Always open pull requests as drafts.

    line 121
  34. Very specific:

    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 …

    line 123

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
copilot-instructions.md

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.

Download now (ZIP)

  • 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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.