Skip to content

Add AI Instruction Files for GitHub Copilot#1078

Open
dwcullop wants to merge 9 commits intoreactivemarbles:mainfrom
dwcullop:docs/ai_instructions
Open

Add AI Instruction Files for GitHub Copilot#1078
dwcullop wants to merge 9 commits intoreactivemarbles:mainfrom
dwcullop:docs/ai_instructions

Conversation

@dwcullop
Copy link
Copy Markdown
Member

@dwcullop dwcullop commented Apr 10, 2026

Summary

Adds comprehensive AI instruction files (.github/copilot-instructions.md + 5 specialized instruction files) to give GitHub Copilot deep context about DynamicData's architecture, operator contracts, Rx requirements, and testing patterns. These files enable Copilot to generate code that respects the library's design patterns, changeset semantics, and testing standards out of the box.

What's Included

6 files, 2,726 lines total:

File Lines Purpose
copilot-instructions.md 271 Main entry point — what DD is, cache vs list comparison, performance importance, Rx contract criticality, SemVer/breaking change policy, repo structure, operator architecture pattern, thread safety, testing philosophy + requirements, anti-patterns
instructions/rx.instructions.md 533 Comprehensive Rx guide — observable contract, composition patterns, all scheduler types, every Disposable helper (Create, Composite, Serial, RefCount, etc.), ~80 standard Rx operators organized by category
instructions/dynamicdata-cache.instructions.md 906 Cache operator bible — SourceCache API, Edit()/ISourceUpdater, ChangeAwareCache/CaptureChanges(), ObservableChangeSet.Create, every cache operator with a per-ChangeReason handling table (what happens on Add, Update, Remove, Refresh)
instructions/dynamicdata-list.instructions.md 604 List operator reference — SourceList API, IExtendedList, ChangeAwareList, ObservableChangeSet.Create<T>, every list operator with per-ListChangeReason handling tables, list↔cache conversion
instructions/testing-cache.instructions.md 227 Cache testing — both observation patterns (AsAggregator vs RecordCacheItems), changeset assertions, TestSourceCache, stub/fixture pattern, stress test examples, per-operator test checklist
instructions/testing-list.instructions.md 185 List testing — ChangeSetAggregator<T>, RecordListItems, list changeset assertions (item vs range), cache-vs-list testing differences, list fixture pattern, stress tests

Design Decisions

  • Specialized instruction files use applyTo frontmatter so they only activate when editing relevant source files, keeping Copilot's context focused
  • Change reason handling tables for every operator document the exact contract — what the operator emits downstream for each input reason. This is the kind of tribal knowledge that prevents subtle bugs.
  • Testing requirements are explicit: all new code must have tests, all bug fixes must have regression tests, and both observation patterns are documented with guidance on when to use which
  • Maintenance rule included: new operators must be added to instruction files, behavior changes must update tables — these are living documents

Why This Matters

DynamicData has ~100 cache operators and ~55 list operators. Each handles 4-8 change reasons differently. Without this context, AI-generated code routinely:

  • Forgets to handle Refresh (causing silent data staleness)
  • Misuses Filter with dynamic predicates when static was intended
  • Creates tests that check message counts instead of final state
  • Ignores disposal, OnError/OnCompleted propagation
  • Uses System.Random instead of deterministic Bogus.Randomizer

These instruction files encode the library's design contracts so Copilot gets it right the first time.

dwcullop and others added 9 commits April 10, 2026 08:33
Three instruction files for GitHub Copilot and AI assistants:

1. .github/copilot-instructions.md — General overview
   - What DynamicData is and why it matters
   - Why performance and Rx compliance are critical
   - Repository structure (public API surface, not internals)
   - Operator architecture pattern (extension method -> internal class -> Run())
   - Thread safety principles
   - Breaking change policy
   - Testing patterns

2. .github/instructions/rx-contracts.instructions.md — Comprehensive Rx guide
   - Core concepts: composability, hot vs cold, Publish/RefCount
   - The Observable contract (serialized notifications, terminal semantics)
   - Scheduler guide: all common schedulers, injection for testability
   - Complete Disposable helper guide: Disposable.Create, CompositeDisposable,
     SerialDisposable, SingleAssignmentDisposable, RefCountDisposable,
     BooleanDisposable, CancellationDisposable
   - Writing custom operators (single-source and multi-source patterns)
   - Operator review checklist
   - Common pitfalls (cold re-subscribe, leak, sync-over-async, Subject exposure)

3. .github/instructions/dynamicdata-operators.instructions.md — Operator guide
   - Changeset model and change reasons
   - Complete operator catalog with detailed code examples:
     Filtering, Transformation, Sorting, Paging, Grouping, Joining,
     Combining, Aggregation, Fan-out/Fan-in, Refresh, Lifecycle,
     Buffering, Binding, Utilities
   - How to write a new operator (10-step guide)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…or catalog

Changes:
- Remove all references to deadlock fixes, queue-drain pattern,
  SharedDeliveryQueue, SynchronizeSafe (these are PR-specific concepts
  that don't exist in the main branch yet)
- Thread safety guidance uses neutral language about Synchronize behavior
- Add comprehensive standard Rx operator reference table (~80 operators)
  organized by category: Creation, Transformation, Filtering, Combining,
  Aggregation, Error Handling, Scheduling, Utility
- Each operator has a concise description

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- rx-contracts.instructions.md → rx.instructions.md (covers far more than contracts)
- copilot-instructions.md now links to both rx.instructions.md and
  dynamicdata-operators.instructions.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Testing section expanded from 7 lines to ~340 lines covering:
- Both observation patterns (AsAggregator vs RecordCacheItems)
- Required test coverage per operator (10 categories)
- Rx contract validation with ValidateSynchronization
- Completion/error propagation testing with TestSourceCache
- Multi-threaded stress test patterns with Barrier
- Regression test requirements (mandatory for all bug fixes)
- Stub/fixture pattern, changeset assertion techniques
- Complete test utilities reference table
- Domain types catalog with Bogus faker usage
- Anti-patterns with bad/good examples

Breaking changes updated: SemVer allows them in major versions,
but they must be explicitly called out to the maintainer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rename dynamicdata-operators → dynamicdata-cache (it's cache-specific)
- Expand cache guide from 278 → 598 lines:
  - SourceCache, ISourceUpdater, Edit() API documented
  - Change<T,K> struct, ChangeReason enum, ChangeAwareCache explained
  - Every operator has a table showing exact handling per ChangeReason
  - Covers: Filter (4 variants), Transform (7 variants), Sort, Page,
    Virtualise, Top, Group (3 variants), all 4 Joins, set operations,
    MergeChangeSets, MergeMany, SubscribeMany, DisposeMany, AutoRefresh,
    lifecycle callbacks, buffering, binding, utilities, property observers
  - Writing a new operator: step-by-step with full code example

- New dynamicdata-list.instructions.md (424 lines):
  - SourceList, IExtendedList, Edit() API
  - ListChangeReason (8 reasons vs cache's 5), ChangeAwareList
  - Every list operator with change reason handling tables
  - List vs Cache comparison table
  - Converting between list and cache
  - Writing a new list operator with checklist

- Update main copilot-instructions.md links

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace 10 broken markdown tables (single data row with no proper
header) with plain prose notes. These were cases where an operator's
behavior is the same as another and a full table wasn't needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The list-vs-cache guidance belongs in the main copilot-instructions.md
where it serves as a top-level navigation aid, not buried in the list
operator file. Also consolidates the instruction file links into the
new section.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Testing section was too cache-specific. Now split into three:

- copilot-instructions.md (Testing section, 73 lines): Philosophy,
  requirements, frameworks, Rx contract validation, regression test
  rules, stress test principles, utilities reference, domain types,
  anti-patterns — all universal, no cache/list specifics

- testing-cache.instructions.md (175 lines, NEW): Both observation
  patterns (AsAggregator + RecordCacheItems), cache changeset
  assertions, TestSourceCache, stub/fixture pattern, cache stress
  tests, per-operator test checklist

- testing-list.instructions.md (143 lines, NEW): List aggregator,
  RecordListItems, list changeset assertions (item vs range changes),
  cache-vs-list testing differences table, list fixture pattern,
  list stress tests, per-operator test checklist

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cache instructions: Added ObservableChangeSet.Create section with
8 overloads documented, 3 practical examples (sync event bridge,
async API loading, SignalR live updates), key behaviors explained.

List instructions: Added ObservableChangeSet.Create<T> section with
sync and async examples (FileSystemWatcher, async stream).

Main instructions: Added 'Maintaining These Instructions' section
requiring new operators to be added to instruction files, operator
behavior changes to update tables, new utilities/domain types to
be documented.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dwcullop dwcullop added the Housekeeping Pull requests for minor code maintenance issues label Apr 10, 2026
@dwcullop dwcullop self-assigned this Apr 10, 2026
@dwcullop dwcullop requested a review from Copilot April 10, 2026 17:56
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a set of GitHub Copilot instruction files under .github/ to provide DynamicData-specific guidance (architecture, Rx contracts, operator semantics, and testing patterns) so AI-generated changes align with library behavior and testing conventions.

Changes:

  • Added main .github/copilot-instructions.md with DynamicData architecture, contracts, and testing guidance.
  • Added operator reference instruction files for Cache and List, plus Rx guidance.
  • Added testing instruction files for Cache and List test patterns/utilities.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
.github/copilot-instructions.md Main DynamicData Copilot instruction entry point (architecture + testing philosophy).
.github/instructions/rx.instructions.md General Rx contract/scheduler/disposable/operator guidance for C# edits.
.github/instructions/dynamicdata-cache.instructions.md Cache operator semantics reference (per-ChangeReason behavior tables + patterns).
.github/instructions/dynamicdata-list.instructions.md List operator semantics reference (per-ListChangeReason behavior tables + patterns).
.github/instructions/testing-cache.instructions.md Cache test observation/assertion/stress patterns and utilities.
.github/instructions/testing-list.instructions.md List test observation/assertion/stress patterns and utilities.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1 to +3
---
applyTo: "src/DynamicData/**/*.cs"
---
Comment on lines +1 to +3
---
applyTo: "src/DynamicData/**/*.cs"
---
@@ -0,0 +1,227 @@
---
@@ -0,0 +1,185 @@
---
Comment on lines +15 to +19
source
.Where(x => x.IsValid) // filter
.Select(x => x.Transform()) // project
.DistinctUntilChanged() // deduplicate
.ObserveOn(RxApp.MainThreadScheduler) // marshal to UI thread
Comment on lines +65 to +68
// RIGHT: use Subject (serializes OnNext calls via Synchronize)
var subject = new Subject<T>();
source1.Subscribe(subject); // Subject.OnNext is NOT thread-safe by default!
// Use Subject with Synchronize if multiple threads call OnNext
// WRONG: two sources can call OnNext concurrently
source1.Subscribe(x => observer.OnNext(Process(x))); // thread A
source2.Subscribe(x => observer.OnNext(Process(x))); // thread B — RACE!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Housekeeping Pull requests for minor code maintenance issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants