Advanced GitHub Copilot Usage
Advanced GitHub Copilot Usage
1 Overview
Tutorial 8 taught Copilot as a personal tool: completions, chat, daily craft. This tutorial graduates it into your team's workflow: AI-assisted code reviews that run before human eyes, test generation that spans unit and integration levels, systematic bug hunts and improvement sweeps, and — the load-bearing theme — the validation discipline that decides how much of any of it to trust.
The closing subject matters most: human-in-the-loop validation and its limits. 'A human reviews it' is the standard answer to AI risk, and it is a good answer — until review volume, anchoring bias, and rubber-stamping quietly hollow it out. Advanced Copilot usage means knowing exactly what the machine checks, what the human checks, and where each one fails.
2 Learning Objectives
After completing this tutorial, you will be able to:
- Run AI-assisted code reviews as a pre-review pass with ranked, line-referenced findings.
- Generate both unit tests and integration tests with Copilot, knowing what each level can and cannot catch.
- Drive systematic bug hunts and improvement sweeps over existing code.
- Build a validation pipeline for AI-generated code: compiler → analyzers → tests → AI self-review → human review.
- Configure repository-level custom instructions so Copilot follows team conventions by default.
- Name the failure modes of human-in-the-loop validation — rubber-stamping, anchoring bias, review fatigue — and design against them.
- Decide, per task, how much validation is enough — and who (or what) provides it.
3 Prerequisites
- Tutorial 8 (GitHub Copilot for .NET Development) — completions, chat, slash commands, and the acceptance discipline.
- Tutorial 5's test honesty toolkit: oracles, assertion review, the sabotage check.
- Working knowledge of NUnit and ideally some exposure to ASP.NET Core integration testing.
- A team codebase (or any realistic project) to practice review and validation workflows on.
4 From Assistant to Workflow: The Trust Pipeline
Basic Copilot use optimizes individual moments: a completion here, a chat answer there. Advanced use optimizes the flow of work: where AI output enters your process, what checks it passes through, and how much human attention each artifact deserves. The organizing idea is a trust pipeline — every AI contribution travels an ordered sequence of validators, each catching what the previous one cannot.
The pipeline's stages, cheapest first: the compiler (hallucinated APIs, type errors — free and instant); static analyzers and formatters (convention drift, known bug patterns — free and instant); tests (behavioral wrongness — cheap once written, and AI writes them); AI self-review (mechanical slips, checklist violations — one extra request); and human review (design judgment, domain correctness, the things only context and taste can catch — expensive, finite, precious). Advanced usage is largely the art of pushing each class of defect to the cheapest stage that reliably catches it.
This inverts a common instinct. Teams worried about AI code quality often respond by demanding more human review — the most expensive validator — while leaving analyzers loose and generated tests unverified. The better posture: tighten the machine stages until they catch everything mechanical, then spend scarce human attention exclusively on what machines cannot judge. The human stays in the loop; the loop is designed so the human's judgment is actually used.
5 AI-Assisted Code Reviews
AI-assisted code review works as a pre-review: the model examines the change before human reviewers do, producing ranked findings the humans then verify and extend. The prompt shape that works, in Copilot Chat with the changed files (or in richer setups, against the PR itself): 'Review this diff against our standards [profile]. Report findings ranked by severity — blocker, major, minor — each with file/line reference, a one-line rationale, and a suggested fix. State explicitly which categories you found nothing in.' The explicit-nothing clause matters: silence must be distinguishable from not-looked.
What AI review reliably catches: convention violations, missing null/edge handling, error-swallowing, obvious inefficiencies, naming drift, missed async patterns — the mechanical middle of review. What it cannot judge: whether the change solves the right problem, fits the architecture's direction, or handles the domain correctly — plus anything requiring runtime knowledge (its performance and concurrency comments are hypotheses). And its recall is probabilistic: an empty finding list proves nothing, which is why AI review augments the checklist and never becomes the gate.
6 Generating Unit and Integration Tests
Tutorial 8 covered unit test generation; the advanced move is extending Copilot up the pyramid to integration tests — and knowing what each level buys. A unit test isolates one behavior with test doubles standing in for dependencies; it runs in milliseconds and localizes failures precisely. An integration test exercises real wiring — the actual HTTP pipeline, real serialization, real database mappings — where an entire class of bugs lives that no amount of unit testing reaches: DI registration errors, middleware ordering, EF Core query translation, contract mismatches between layers.
Copilot generates integration tests well when you supply the pattern: an exemplar integration test using your stack's conventions (for ASP.NET Core, typically a WebApplicationFactory-based test class), the endpoint or flow under test, and the scenario list. The prompt shape: 'Generate integration tests for the POST /orders endpoint using the same pattern as this exemplar: real pipeline, in-memory or containerized database per our convention, covering: valid order → 201 with location header; invalid payload → 400 with validation details; duplicate idempotency key → 409. Include arrange helpers consistent with the exemplar.'
[TestFixture]
public class OrdersEndpointTests
{
private WebApplicationFactory<Program> _factory = null!;
private HttpClient _client = null!;
[SetUp]
public void SetUp()
{
_factory = new WebApplicationFactory<Program>();
_client = _factory.CreateClient();
}
[TearDown]
public void TearDown()
{
_client.Dispose();
_factory.Dispose();
}
[Test]
public async Task PostOrder_ValidPayload_Returns201WithLocation()
{
var response = await _client.PostAsJsonAsync("/orders", new
{
customerId = 42,
lines = new[] { new { sku = "ABC-1", qty = 2 } }
});
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Created));
Assert.That(response.Headers.Location, Is.Not.Null);
}
}
Division of labor between the levels: generate unit tests for logic-heavy classes (fast feedback, precise localization, mock the edges), integration tests for wiring-heavy flows (endpoints, persistence, auth policies). The review discipline scales up with the level: integration tests are slower and flakier by nature, so demand determinism in the prompt — seeded data builders, no shared state between tests, explicit cleanup — and apply the tutorial 5 honesty rules unchanged: a green integration suite that survives sabotage of the endpoint's core logic is theater, not protection.
7 Identifying Bugs and Improvements
Beyond reacting to failures, Copilot supports proactive sweeps: pointed prompts that hunt classes of defects across code you select. The craft is asking for specific failure classes rather than 'find bugs' — the generic ask produces generic nitpicks, while a targeted ask focuses the model's pattern-matching where it excels:
- Concurrency sweep: 'Examine this class for async/await mistakes: missing awaits, async void, .Result/.Wait() deadlock risks, unawaited fire-and-forget, missing cancellation propagation. Line references.'
- Resource sweep: 'Find undisposed IDisposables, missing using statements, HttpClient misuse, and connection/stream leaks.'
- Null-safety sweep: 'With nullable reference types in mind, find dereferences that can throw and parameters missing guards.'
- Edge-case sweep: 'For each public method, list inputs that would break it: empty, null, negative, maximum, duplicate, concurrent.'
- Improvement sweep: 'Rank the top 5 refactoring opportunities by payoff: name the code smell, the behavior-preserving fix, and the risk. Do not change anything.'
Two disciplines keep sweeps honest. First, findings are hypotheses: every claimed bug gets verified — reproduced with a test or traced in the debugger — before it earns a fix, exactly like tutorial 3's ranked-hypotheses rule; a model 'confirming' its own finding is not confirmation. Second, improvements are proposals: the improvement sweep explicitly forbids changes ('do not change anything'), because the decision of what is worth churning belongs to humans with context about risk, roadmap, and hot paths. The best output of an improvement sweep is a prioritized backlog, not a diff.
8 Validating AI Code — and the Limits of Human-in-the-Loop
Assemble the pieces into the validation pipeline every AI-assisted change should travel: (1) the compiler — free, catches hallucinated APIs and type errors; (2) analyzers and formatters — free, catch convention drift and known bug patterns; (3) tests — unit and integration, honesty-checked, catching behavioral wrongness; (4) AI self-review — one request, catching checklist violations and mechanical slips; (5) human review — the finite, precious stage for design, domain, and intent. The pipeline's design goal: nothing mechanical survives to stage 5, so stage 5's scarce attention is spent entirely on judgment.
Human-in-the-loop is the right terminal control — and it is a resource with failure modes, not a magic word. It degrades predictably: with volume (fatigue), with AI assistance itself (anchoring — reviewers under-look where the model said clean), and with time (rubber-stamping as gates become ritual). Designing against the limits: keep human gates few and consequential rather than many and diluted; never let the AI's own review be the only input a human sees (show the diff, not just the summary); rotate deep-review duty so fresh eyes hit high-risk changes; and measure the gate — approval latency, edit rate, rejection rate. A gate that approves 100% of items at ten seconds each is not a gate; it is a metric pretending to be a control.
9 Team-Scale Copilot: Instructions, Policies, CI
- Repository custom instructions: a checked-in instructions file (e.g. .github/copilot-instructions.md) that steers Copilot for everyone in the repo — conventions, framework versions, forbidden patterns, test style — the standards profile (tutorial 4) applied automatically instead of pasted.
- Copilot's PR-integration features (availability varies by plan/platform): AI-generated PR summaries and review suggestions — useful inputs, same non-gate status as any AI review.
- CI as the enforcement floor: analyzers, formatters, test runs, and coverage thresholds run on every PR — the machine stages of the pipeline, executed without exception.
- Organization policy settings: enablement scope, public-code filtering, telemetry — reviewed at rollout (tutorial 8) and revisited as the product evolves.
- Team prompt assets: shared review checklists, sweep prompts, and test-generation instructions kept in the repo beside the code they serve — tutorial 7's library, team edition.
Custom instructions deserve emphasis: they are the highest-leverage team configuration, because they fix the context problem at the source — every developer's Copilot sees the team's conventions on every request, without anyone remembering to paste a profile. Keep the file short, concrete, and versioned like code; audit it when suggestion quality drifts; and mirror its rules in analyzers, because instructions raise compliance while analyzers enforce it (the tutorial 4 truth, one level up).
10 The Advanced Workflow Catalog
| Workflow | Mechanism | The guardrail |
|---|---|---|
| Pre-review every PR | Diff + standards profile → ranked findings with lines | Human verifies findings; empty list proves nothing |
| Integration-test an endpoint | Exemplar + scenario list → WebApplicationFactory-style suite | Determinism demanded; sabotage check applies |
| Pre-merge concurrency sweep | Targeted async/await failure-class prompt | Findings verified before fixes |
| Quarterly improvement sweep | Ranked refactoring backlog per module | Proposals only — humans pick what's worth churn |
| Bug-fix validation | Regression test (fails pre-fix) + AI review of the fix | Diagnosis confirmed before fixing (tutorial 3) |
| Onboard to unfamiliar module | /explain layers + risk inventory + characterization tests | Explanations verified against source |
| Standards rollout | Custom instructions file + mirrored analyzers | Instructions raise compliance; analyzers enforce |
| Review-load management | Machine stages hardened; human gates scoped + instrumented | Gate metrics watched: edit rate, rejection rate |
Read the guardrail column as the point: every advanced workflow is a basic workflow plus the check that keeps it honest at scale. Teams that adopt the left column without the right column get tutorial 8's warning — speed with a defect tax — at team scale.
11 Code Examples in C#
A team review-prompt asset — checked into the repo, used by everyone, versioned like code:
public static class ReviewPrompts
{
// v5: added explicit-nothing clause + async category (2026-09).
public const string PreReview = """
Review the following diff as a first-pass reviewer.
Categories: correctness, async/await mistakes, error handling,
null-safety, naming/conventions, security-sensitive patterns.
Report: findings ranked by severity (blocker/major/minor),
each with file:line, a one-line rationale, and a suggested fix.
For every category with NO findings, state that explicitly.
Do not comment on style covered by our analyzers.
Do not propose refactors unrelated to the diff.
""";
}
And the validation pipeline expressed as a checklist type — the kind of small artifact that turns discipline into default:
public sealed record AiChangeValidation
{
public bool CompilesClean { get; init; } // stage 1: compiler
public bool AnalyzersPass { get; init; } // stage 2: analyzers/format
public bool TestsGreen { get; init; } // stage 3: unit + integration
public bool SabotageCheckDone { get; init; } // stage 3b: suite honesty (tutorial 5)
public bool AiSelfReviewDone { get; init; } // stage 4: one extra request
public bool HumanReviewDone { get; init; } // stage 5: judgment, not ritual
public bool ReadyToMerge =>
CompilesClean && AnalyzersPass && TestsGreen &&
SabotageCheckDone && AiSelfReviewDone && HumanReviewDone;
}
12 Step-by-Step: An AI-Assisted PR Review, End to End
A realistic pull request — a teammate's Copilot-assisted feature adding an order-cancellation endpoint — reviewed with the full pipeline. Replay it on your next real PR.
- Machine gate first: CI has run — build clean, analyzers clean, tests green. You look at nothing until this is true; anything else wastes attention on what machines catch free.
- AI pre-review: run the team's PreReview prompt against the diff in Copilot Chat. It returns: one major (missing cancellation propagation in the new service call), two minors (naming, a redundant null check), and explicit 'nothing found' in security and error handling.
- Verify the major: open the code path — confirmed, the CancellationToken stops at the controller. A real finding; comment with the fix.
- Anchoring counter-move: before trusting the clean categories, read the diff yourself for the two things AI review is weakest at — does this change fit the architecture, and is the domain logic right? You find a domain question the model could never catch: cancellation is allowed for shipped orders, which the ticket excludes. That's the review's most important finding, and a human made it.
- Test scrutiny: the PR includes generated tests. Names against the scenario list — the duplicate-cancellation case is missing; request it. Assertions spot-checked; one asserts on the mock instead of the response — request the fix (tutorial 5's classic).
- Sabotage spot-check (risk-based, not every PR): the cancellation state check is this PR's crux — flip it locally, run the suite: two tests go red. The suite earns its green for this change.
- Human verdict: approve with changes — the major, the missing case, the mock assertion, and the domain question back to the author. Merge happens after re-review of those points.
- Close the loop (30 seconds): the missing-cancellation-propagation finding recurs across PRs — add it to the custom instructions file so Copilot stops generating the pattern at the source.
13 Limitations and Caveats
- AI review recall is probabilistic: an empty findings list is not a clean bill of health, and 'nothing found in security' means 'nothing pattern-matched', not 'secure'. The human read of the diff stays.
- Anchoring is insidious precisely because the AI's framing is usually right — the 95% of good calls train you to under-verify the 5%. Structural counters (read the diff before the findings on high-risk PRs) beat willpower.
- Integration tests amplify flakiness risks: shared state, timing, real IO. Demand determinism in generation prompts and treat a flaky generated suite as worse than none — it trains the team to ignore red.
- Sweeps produce false positives confidently; verification-before-fix is not optional. They also produce false negatives silently; sweeps supplement, never replace, testing and review.
- Custom instructions steer probabilistically — they are not policy enforcement. Mirror every rule that matters in analyzers or CI.
- Human gates degrade measurably with volume; an uninstrumented gate should be presumed degraded. Edit and rejection rates are the health check.
- Team features (PR summaries, review integrations, instruction file mechanics) vary by plan and evolve quickly — verify current capabilities against official documentation.
14 Best Practices and Common Mistakes
The advanced habit set:
- Order the pipeline by cost: compiler → analyzers → tests → AI review → human judgment; push every defect class to its cheapest reliable catcher.
- Demand ranked, line-referenced, explicit-nothing findings from AI review; verify before acting.
- Generate tests at both levels — unit for logic, integration for wiring — with determinism demanded and honesty checks applied.
- Run targeted sweeps (concurrency, resources, null-safety, edge cases) at defined moments; verify findings before fixes; keep improvement sweeps as backlogs, not diffs.
- Encode team conventions in custom instructions and mirror the enforceable subset in analyzers.
- Scope human gates to genuine judgment calls; instrument them; rotate deep-review duty.
- Feed recurring findings back into instructions and analyzers — fix the source, not just the instances.
The mistakes that appear at team scale:
- Responding to AI-quality worries with more human review instead of harder machine stages — spending the most expensive validator on the cheapest defects.
- Treating an empty AI findings list as approval.
- Letting the AI's summary be the only thing the human reads — anchoring by design.
- Shipping flaky generated integration suites that teach the team to ignore red.
- Applying sweep fixes without verifying the findings.
- Custom instructions that contradict the analyzers — every generation wastes an Improve turn.
- Uninstrumented human gates presumed healthy — rubber-stamping discovered only after the incident.
- Forgetting the terminal rule: merge is a human decision, made on evidence the pipeline assembled.
20 Summary & Key Takeaways
- Advanced Copilot usage is workflow design: a trust pipeline where each validator catches what it is cheapest to catch — compiler, analyzers, tests, AI review, then humans.
- AI pre-review absorbs the mechanical middle with ranked, line-referenced, explicit-nothing findings — humans verify, extend, and keep the judgments only they can make.
- Generate tests at both levels: unit for logic, integration for wiring — with determinism demanded and tutorial 5's honesty checks applied unchanged.
- Hunt bugs with targeted sweeps and treat findings as hypotheses; improvement sweeps produce backlogs, not diffs.
- Human-in-the-loop is a finite resource with failure modes — fatigue, anchoring, rubber-stamping — managed by design and instrumentation, not exhortation.
- Custom instructions encode team conventions at the generation source; analyzers enforce what instructions request; recurring findings feed back into both.
- The terminal rule never moves: merge is a human decision on machine-assembled evidence.
Module 2 is complete: Copilot as daily craft and as team workflow. Module 3 changes the direction of the relationship — from AI helping you write applications to applications you write calling AI: Azure OpenAI, from first concepts to production code.
21 Next Steps
Continue with the next tutorial in the path: Overview of Azure OpenAI — the service model, deployments, security posture, and the concepts underlying every AI feature you will build in the rest of this course.
- Practice: run the section 12 walkthrough on your next real PR — including the anchoring counter-move and the 30-second close-the-loop.
- Practice: draft your team's custom instructions file from the conventions your reviews enforce most often.
- Practice: generate one integration test suite from an exemplar, then audit it for determinism before running it.
- Practice: run one targeted concurrency sweep on an async-heavy class; verify (or falsify) every finding.
- Reading: your CI configuration — map which pipeline stages exist today and which defect classes currently survive to human review.
15 Quiz
Pick an answer for each question, then press Check answer. (Notes are disabled in this tab.)
1. What is the correct role of AI-assisted code review in a team workflow?
2. Why demand 'state explicitly which categories you found nothing in' from AI review?
3. What class of bugs do integration tests catch that unit tests structurally cannot?
4. What must an integration-test generation prompt demand to avoid a suite worse than none?
5. Why do targeted sweeps ('find async/await mistakes') outperform 'find bugs'?
6. A sweep reports a probable race condition. What happens next?
7. Why should improvement sweeps end in a backlog rather than a diff?
8. Order the validation pipeline stages by cost, cheapest first.
9. What is anchoring bias in AI-assisted review?
10. What is rubber-stamping, and what makes a gate susceptible?
11. Which metric most directly reveals a degraded human gate?
12. What are repository custom instructions for?
13. The AI pre-review found nothing in the 'security' category. The correct interpretation is:
14. In the walkthrough, which finding could ONLY the human make?
15. As AI output volume grows, what happens to 'a human checks everything'?
16 Exam Questions
Try answering each question yourself before expanding the model answer.
1. Define the trust pipeline for AI-assisted development: stages, ordering rationale, and design goal.
2. Specify a production-grade AI pre-review prompt and justify each element.
3. Compare unit and integration test generation with Copilot: what each level catches, prompt requirements, and review differences.
4. Design a sweep program for a mature codebase: which sweeps, when, and the disciplines that keep them honest.
5. Name and analyze the three failure modes of human-in-the-loop validation, with structural countermeasures for each.
6. Explain custom instructions: mechanism, relationship to analyzers, and maintenance discipline.
7. Argue for and against sabotage-checking on every PR, and state a defensible policy.
8. The walkthrough's most important finding came from the human, not the AI. Generalize: what review contributions are structurally human, and what protects the capacity to make them?
9. Design the metrics for an AI-assisted review process: what you measure, what each signals, and the traps.
10. A teammate proposes auto-merging PRs when AI review returns no blockers and CI is green. Evaluate.
11. How does the tutorial 5 test-honesty discipline extend to integration tests, and what new failure modes appear at that level?
12. Describe the close-the-loop practice from the walkthrough and argue why it compounds.
13. Propose a rollout plan for the advanced workflows in a 10-developer team currently using Copilot casually.
14. Explain why 'more human review' is often the wrong answer to AI code-quality concerns, and what the right answer is.
15. Scenario: after six months of heavy Copilot use, a team's velocity is up 40%, escaped defects up 25%, and two incidents traced to 'reviewed' AI code nobody remembers scrutinizing. Diagnose fully and prescribe.
17 Flashcards
Click a card to reveal the back.
Trust pipeline (5 stages)
Pipeline design goal
AI pre-review prompt essentials
Explicit-nothing clause
What AI review can't judge
Unit vs integration tests
Integration-test prompt demands
Flaky generated suite
Targeted sweeps
Sweep discipline
HITL failure mode: anchoring bias
HITL failure mode: rubber-stamping
Gate health check
Custom instructions
Close the loop
The terminal rule
18 Interview Questions & Answers
1. How would you integrate AI review into a team's PR process?
2. What's the difference between how you'd use Copilot for unit versus integration tests?
3. Tell me about proactive bug-hunting with AI.
4. What does 'validating AI-generated code' actually mean in your workflow?
5. What are the limits of human-in-the-loop validation?
6. How do you prevent reviewers from being anchored by AI findings?
7. What are repository custom instructions and how do you use them well?
8. Would you ever let AI review gate a merge?
9. How do you measure whether an AI-assisted review process is healthy?
10. A sweep flags 15 'bugs' in a legacy module. Walk me through your handling.
11. How does test honesty change at the integration level?
12. What's your 'close the loop' practice and why do you rate it so highly?
13. Your team's AI-assisted velocity is up but incident count is creeping. Board asks if the AI was a mistake. Your answer?
14. Where should a team be one year into advanced Copilot adoption?
15. Sum up your philosophy of advanced AI-assisted development.
19 Glossary
- AI-assisted code review
- A model pass over the diff producing ranked, line-referenced findings before human review — a pre-filter, never the gate.
- Pre-review
- The AI stage between CI and humans; absorbs the checklist-able middle so human attention reaches design and domain intact.
- Explicit-nothing clause
- Requiring 'no findings in category X' statements so silence is distinguishable from not-looked; recall remains probabilistic either way.
- Severity ranking
- Blocker/major/minor ordering demanded from AI findings so humans triage instead of wading.
- Trust pipeline
- The ordered validators every AI contribution travels: compiler → analyzers → tests → AI self-review → human review, cheapest first.
- Deterministic gate
- The machine stages — compiler, analyzers, tests, CI — that catch mechanical defects free, protecting human attention.
- Integration test
- A test exercising real wiring (HTTP pipeline, serialization, database) — catching DI, ordering, and translation bugs unit tests structurally miss.
- WebApplicationFactory
- The standard ASP.NET Core in-process test host pattern for integration tests; the exemplar shape given to Copilot for endpoint suites.
- Test double
- Mocks, stubs, fakes — dependency substitutes that make unit tests fast and precise, and that hide exactly the wiring integration tests exist to check.
- Determinism (tests)
- Seeded data, isolated state, explicit cleanup — demanded in generation prompts because flaky suites train teams to ignore red.
- Targeted sweep
- A bug hunt scoped to a named failure class (async/await, disposal, null-safety) — a checklist aimed at the model's pattern-matching strength.
- Improvement sweep
- A ranked refactoring-opportunity backlog per module — proposals only; humans decide what is worth churn.
- Finding-as-hypothesis
- The sweep discipline: every claimed bug is reproduced or traced before a fix; model self-confirmation is not confirmation.
- Validation pipeline
- The concrete checklist an AI-assisted change completes before merge: compile, analyzers, tests, sabotage check, AI self-review, human review.
- Human-in-the-loop (limits)
- The terminal control — powerful, finite, and degrading predictably with volume via fatigue, anchoring, and rubber-stamping.
- Review fatigue
- Attention decline across sequential reviews; countered by shrinking the human surface and rotating deep-review duty.
- Anchoring bias
- The AI's confident framing narrowing independent judgment; countered by diff-before-findings on high-risk changes.
- Rubber-stamping
- Reflexive approval at volume — control on paper, judgment gone; detected by near-total approval at trivial latency.
- Gate instrumentation
- Measuring approval latency, edit rate, and rejection rate so gate degradation is visible before incidents reveal it.
- Custom instructions
- A checked-in repository file steering Copilot for all developers — conventions stated once, mirrored in analyzers for enforcement.
- Close the loop
- Feeding recurring findings into instructions and analyzers — fixing generation at the source so finding classes go extinct.
- Terminal rule
- Merge is a human decision made on pipeline-assembled evidence; automation improves the evidence, never the verdict.