A year ago I started keeping a log of every task where I used AI coding assistance and the quality of the output. Not a formal study. A personal note in my task manager with a one-line assessment: what I asked, what I got, whether it was usable, and whether I would delegate that category again. After 12 months of entries, the pattern is clear enough to write about.
The short version: AI is a highly capable junior engineer who has read every tutorial and documentation page ever published but has never worked in a production codebase under deadline pressure. It knows patterns extremely well. It does not know your system, your constraints, your team's history, or why that specific service was designed the way it was. Delegate accordingly.
What I Delegate Without Hesitation
Boilerplate and Scaffolding
Generating a new Angular standalone component with OnPush change detection, a corresponding spec file, an interface for its inputs, and the basic SCSS structure takes me well under a minute with an AI assistant. By hand it takes several minutes. Over a day with multiple components, this adds up. The output is reliable, consistent with the patterns I have configured in the project's custom instructions file, and requires minimal review.
// Prompt I use for scaffolding:
// "Create a standalone Angular component called UserProfileCard.
// It should accept a User input (use the existing User interface from core/models).
// OnPush change detection. Include a loading skeleton state.
// SCSS using design tokens. Spec file with a basic render test."
// Output quality: usable on the first pass, small adjustments for project-specific patterns
// Time saved: most of the typing per component
// Review required: light scan for any deviances from the project rulesUnit Tests for Pure Functions
This is where I see the highest quality output consistently. Given a pure function with clear inputs and outputs, AI generates comprehensive unit tests including edge cases I might have missed. I provide the function signature and a description of the expected behavior, and the test suite comes back with happy path, boundary conditions, null/undefined handling, and type validation tests.
// Function I provide:
export function formatCurrency(
amount: number,
currency: string,
locale: string
): string {
if (amount < 0) throw new Error('Amount must be non-negative');
return new Intl.NumberFormat(locale, {
style: 'currency',
currency,
minimumFractionDigits: 2
}).format(amount);
}
// AI-generated tests cover:
// - Standard formatting for CAD/USD/EUR
// - Zero amount
// - Large amounts with thousands separators
// - Locale differences (en-CA vs fr-CA)
// - Negative amount throws error
// - Invalid currency code behavior
// Output quality: the most reliable category in my log, week after week
// Time saved: most of the test-writing time per functionRegex and String Manipulation
I no longer write regular expressions from scratch. I describe the pattern I need in plain English, ask for the regex, ask for test cases, and verify against them. The AI's regex output is more readable than what I used to produce under time pressure and the test cases it generates often reveal edge cases I had not considered. Validation regex for Canadian postal codes, SIN format checks, phone number normalization. All delegated. Note the split: the format rule is generic and safe to hand over, while what the code then does with the value, masking it, logging it, storing it, is not, and that part I write myself.
Refactoring Known Patterns
Converting an NgModule-declared component to a standalone component, migrating untyped reactive forms to the typed forms API, updating older RxJS code to newer RxJS patterns, extracting a repeated block into a shared component. These are mechanical transformations where the rules are known and AI executes them accurately. I still review the output, but the review is confirmation, not reconstruction.
CSS and SCSS Mechanics
Complex CSS layouts, animation keyframes, print-specific stylesheets, CSS grid template areas. These are areas where AI produces correct output that would take me significantly longer to write manually. I describe the layout behavior I need and review the output for token compliance and browser compatibility.
Documentation and JSDoc
I give AI a function or service and ask it to generate JSDoc comments. It produces accurate, well-structured documentation that I then review and adjust for nuance. This used to be the most procrastinated task on any project. Now it is a 30-second prompt.
Where AI Fails: What I Never Delegate
Architecture Decisions
Should this feature live in a shared library or the host application? Should we use a facade pattern or expose the store directly? Should this data be fetched eagerly or lazily? These decisions require understanding the codebase's history, the team's capabilities, the deployment model, the performance budget, and the long-term roadmap. AI will give you an answer. The answer will be plausible and well-reasoned. It will be based on the information you provided in the prompt, which is never the full picture.
AI will recommend splitting a service into three microservices without knowing whether your deployment pipeline can ship services independently. It will recommend an NgRx implementation for state your team already plans to move to a different pattern. Architecture decisions require context that lives outside the codebase.
Domain-Specific Business Logic
Regulated business logic is specific and shaped by decades of product evolution. Take insurance claims as a neutral example: which policy terms apply on the date of loss, what the deductible does to the payout, when a file has to be escalated to an adjuster. AI has no knowledge of a given carrier's rules and will confidently generate plausible-looking code that is wrong for the domain, and wrong in a way that reads as correct in review. I do not prompt AI with these tasks at all. I write them myself with the product owner's specification open beside the editor.
Security-Sensitive Code
Authentication flows, authorization checks, encryption utilities, token validation, consent verification. I write these manually, insist on a review before merge, and do not iterate on them with AI. The risk of a subtly wrong suggestion in this category is too high, and the review effort needed to trust the output makes it no faster than writing it myself.
Performance-Critical Paths
When I am optimizing a render-critical component, a complex RxJS pipeline that handles high-frequency events, or a virtual scrolling implementation, I write and profile manually. AI-generated code is correct in terms of behavior but rarely optimal in terms of performance. It does not know your change detection strategy, your bundle size budget, or which calls are happening in the critical rendering path.
How My Delegation Has Evolved
When I started the log, AI was already part of my daily work. What I did not have was a map. I delegated broadly and judged each result on its own, so I kept handing over categories that came back needing a rewrite, and kept doing by hand some work the tool handles well. The first three months of entries were mostly about sorting those two lists.
By month six, the log had given me a set of prompting patterns specific to my workflow: function signatures before implementations, tests before code, and constraints stated explicitly ('this runs in OnPush context,' 'this must not trigger zone.js change detection'). The patterns themselves are simple. Applying them to every prompt, not only when I remembered, is what moved the output quality.
By month twelve, my workflow had stabilized. AI handles a large share of my keystrokes on any given day, primarily in test files, SCSS, and boilerplate. The rest is architecture, business logic, review, and anything that requires knowledge of how our specific system works. That share is genuinely valuable because it is the part I found least interesting and most time-consuming.
- High confidence delegation: unit tests, boilerplate, regex, SCSS, refactoring, JSDoc
- Medium confidence delegation: integration test scaffolding, complex RxJS pipelines (with review), data transformation utilities
- Low confidence delegation: NgRx effects with side effects, error handling strategies, anything touching auth
- Never delegate: architecture decisions, domain business logic, security-sensitive code, performance-critical paths
The Honest Assessment
AI coding tools have made me meaningfully faster on the tasks they handle well. They have not made me a better architect, a better domain expert, or a better reviewer. The engineers I know who are getting the most value from these tools are the ones who are clear about the distinction. They use AI to accelerate execution and reserve their own judgment for the decisions that require it.
The best use of AI in development is not to replace thinking. It is to eliminate the work that does not require it, so you have more time and energy for the work that does.
Track your delegations for a month. Not formally. Just a mental note of what you asked AI to do and whether the result was usable without significant revision. You will quickly build a personal map of where the tool earns your trust and where it wastes your time. That map is more valuable than any generic guide to AI prompting, because it is calibrated to your specific domain, codebase, and working style.
References
- GitHub Copilot repository custom instructions. https://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/add-custom-instructions/add-repository-instructions
- GitHub Copilot. https://github.com/features/copilot