Skip to content

Commit 3966991

Browse files
Copilotkraenhansen
andcommitted
Add comprehensive analysis and suggestions for improving Copilot instructions
Co-authored-by: kraenhansen <1243959+kraenhansen@users.noreply.github.com>
1 parent f11d1d5 commit 3966991

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# Suggested Improvements to Copilot Instructions
2+
3+
Based on the comparison between the AI-generated approach (this PR) and the human-written approach (PR #294), here are suggestions to improve the Copilot instructions to help produce better results in the future.
4+
5+
## Key Lessons Learned
6+
7+
### 1. **Simpler is Better: Extend Existing Workflows Instead of Creating New Ones**
8+
9+
**What I Did (Overly Complex):**
10+
- Created a completely new `.github/workflows/check-visionos.yml` workflow file
11+
- Added extensive diagnostic steps and special case handling
12+
- Tried to handle all edge cases in the workflow itself
13+
14+
**What Should Have Been Done (PR #294 Approach):**
15+
- Extended the existing `.github/workflows/check.yml` with a new job
16+
- Used conditional execution: `if: github.ref == 'refs/heads/main' || contains(github.event.pull_request.labels.*.name, 'Ferric 🦀')`
17+
- Kept the workflow simple and focused on just the necessary steps
18+
19+
**Instruction Improvement:**
20+
```markdown
21+
## Workflow Guidelines
22+
23+
- **Prefer extending existing workflows** over creating new ones unless there's a strong reason
24+
- **Use conditional job execution** (`if:` clauses) rather than separate workflow files
25+
- **Keep workflows simple** - avoid extensive diagnostic steps unless debugging a specific issue
26+
- **Follow existing patterns** in the repo's workflows for consistency
27+
```
28+
29+
### 2. **Function Naming: Be Clear About What Functions Actually Do**
30+
31+
**What I Did (Confusing):**
32+
- Tried to make `getInstalledTargets()` return tier 3 targets based on build-std availability
33+
- Created confusion about what "installed" means
34+
35+
**What Should Have Been Done (PR #294 Approach):**
36+
- Renamed to `ensureAvailableTargets()` to better reflect that it checks availability, not just installation
37+
- Kept `getInstalledTargets()` doing exactly what it says - returning installed targets from rustup
38+
- Created separate `assertNightlyToolchain()` function for tier 3 validation
39+
40+
**Instruction Improvement:**
41+
```markdown
42+
## Code Quality Guidelines
43+
44+
- **Function names should precisely describe what they do** - avoid stretching function purposes
45+
- **When logic changes, consider renaming** - if a function does more than its name suggests, rename it
46+
- **Separate concerns** - create new functions rather than overloading existing ones
47+
- **Follow existing naming patterns** in the codebase (e.g., `ensureAvailableTargets` vs `ensureInstalledTargets`)
48+
```
49+
50+
### 3. **Minimal Changes: Don't Over-Engineer Solutions**
51+
52+
**What I Did (Over-Engineered):**
53+
- Added complex build-std detection logic
54+
- Created extensive error messaging with multiple steps
55+
- Built comprehensive diagnostic capabilities
56+
- Tried to handle every possible edge case upfront
57+
58+
**What Should Have Been Done (PR #294 Approach):**
59+
- Simple tier 3 target detection using a `Set`
60+
- Straightforward `assertNightlyToolchain()` check
61+
- Clear, concise error messages with actionable commands
62+
- Let users handle their own specific edge cases
63+
64+
**Instruction Improvement:**
65+
```markdown
66+
## Simplicity Principles
67+
68+
- **Start with the simplest solution that works** - don't over-engineer
69+
- **Use standard library features** when available (e.g., `Set.intersection()`)
70+
- **Avoid premature optimization** - don't add diagnostics unless there's a known problem
71+
- **Trust the user** - provide clear error messages but don't try to handle every edge case
72+
- **Incremental complexity** - add complexity only when actually needed, not preemptively
73+
```
74+
75+
### 4. **Target Management: Simple Data Structures Are Sufficient**
76+
77+
**What I Did (Complex):**
78+
- Created `TIER_3_TARGETS` as a readonly array with complex type assertions
79+
- Added helper functions like `isTier3Target()` with type casting
80+
- Created conditional logic that checked if targets were in multiple places
81+
82+
**What Should Have Been Done (PR #294 Approach):**
83+
- Simple `const THIRD_TIER_TARGETS: Set<TargetName> = new Set([...])`
84+
- Used `Set.intersection()` for checking which tier 3 targets are requested
85+
- Simple `has()` method for checking membership
86+
87+
**Instruction Improvement:**
88+
```markdown
89+
## Data Structure Guidelines
90+
91+
- **Use appropriate data structures** - `Set` for membership testing, not arrays
92+
- **Leverage built-in methods** - `Set.intersection()`, `Set.has()` vs custom helper functions
93+
- **Avoid unnecessary type gymnastics** - keep types simple and clear
94+
- **Consistency** - follow patterns already established in the codebase
95+
```
96+
97+
### 5. **Documentation: Link to Code, Not Just Docs**
98+
99+
**What I Did:**
100+
- Added extensive JSDoc comments with links to Rust documentation
101+
- Created multi-step instructions in error messages
102+
- Verbose explanations throughout
103+
104+
**What Should Have Been Done (PR #294 Approach):**
105+
- Minimal, focused comments
106+
- Simple function names that are self-documenting
107+
- Let `assertFixable` provide the command to run
108+
- Keep error messages concise and actionable
109+
110+
**Instruction Improvement:**
111+
```markdown
112+
## Documentation Standards
113+
114+
- **Self-documenting code** - good names reduce need for comments
115+
- **Concise error messages** - provide the fix command, not a tutorial
116+
- **Link to official docs only when necessary** - don't overdo it
117+
- **Follow existing documentation patterns** in the codebase
118+
```
119+
120+
### 6. **Testing Strategy: Use Existing Infrastructure**
121+
122+
**What I Did:**
123+
- Created separate workflow for visionOS testing
124+
- Added custom diagnostic steps
125+
- Tried to test in isolation
126+
127+
**What Should Have Been Done (PR #294 Approach):**
128+
- Added job to existing workflow: `test-ferric-apple-triplets`
129+
- Used conditional execution based on branch or label
130+
- Leveraged existing test infrastructure and patterns
131+
132+
**Instruction Improvement:**
133+
```markdown
134+
## Testing Approach
135+
136+
- **Use existing test infrastructure** - don't create parallel test systems
137+
- **Conditional testing** - use branch checks or labels to control when tests run
138+
- **Integration over isolation** - tests should work within the existing workflow
139+
- **Label-based triggers** - follow the pattern of using labels like 'Ferric 🦀' for opt-in testing
140+
```
141+
142+
## Recommended Additions to `.github/copilot-instructions.md`
143+
144+
Add a new section:
145+
146+
```markdown
147+
## Code Change Philosophy
148+
149+
### Minimal, Incremental Changes
150+
- **Start simple** - implement the minimal solution that solves the problem
151+
- **Extend, don't replace** - modify existing code/workflows rather than creating new ones
152+
- **Follow patterns** - look at how similar problems are solved elsewhere in the codebase
153+
- **Incremental complexity** - add features only when actually needed
154+
155+
### Rust/Cargo Integration
156+
- **Use `assertFixable`** for validation that has a clear fix command
157+
- **Target management** - use `Set` for collections of targets, leverage built-in methods
158+
- **Tier 3 targets** - these require nightly Rust with `rust-src` component
159+
- **Avoid complex detection logic** - simple checks are usually sufficient
160+
161+
### Workflow Development
162+
- **Extend existing workflows** with new jobs rather than creating separate files
163+
- **Conditional execution** - use `if:` clauses for branch/label-based job triggers
164+
- **Keep it simple** - minimal steps, clear purpose, follow existing patterns
165+
- **Test efficiency** - use labels to control expensive test jobs
166+
```
167+
168+
## Summary
169+
170+
The key difference between the two approaches is that PR #294 takes a **simpler, more direct approach** that:
171+
1. Extends existing infrastructure rather than building new
172+
2. Uses appropriate data structures and built-in methods
173+
3. Has clear, focused function responsibilities
174+
4. Avoids over-engineering and premature optimization
175+
5. Follows established patterns in the codebase
176+
177+
These principles should guide future AI-assisted development to produce code that better matches the project's style and philosophy.

0 commit comments

Comments
 (0)