Agent Skills in Claude Code and Visual Studio Code: Setup, Benefits, Risks, and a Step-by-Step Example
The hardest bugs to find during code review aren't bugs at all. They're things that should be there but aren't. If code is wrong, it's visible when you read it. But if something is missing from the code entirely — something that should be there according to requirements or business logic? That's invisible. It doesn't exist in the diff. AI review tools won't flag it.
Here's a PR titled "Implement account deactivation". The code looks correct at first glance:
@PostMapping("/users/{userId}/deactivate")
public ResponseEntity<Void> deactivateUser(
@PathVariable String userId,
@AuthenticationPrincipal UserDetails currentUser) {
if (!currentUser.getUsername().equals(userId)) {
throw new ForbiddenException("Only the account owner can delete the account.");
}
User user = userRepository.findById(userId)
.orElseThrow(() -> new UserNotFoundException(userId));
user.setStatus(UserStatus.DEACTIVATED);
user.setDeactivatedAt(LocalDateTime.now());
userRepository.save(user);
return ResponseEntity.noContent().build();
}
Authentication check exists. Exception handling is present. Status changes are properly saved. An AI review tool would pass this code. But a good human reviewer asks: What else is connected to this user that needs to be handled during deactivation?
The questions flow:
None of this is in the code. It's not a bug — it's missing functionality that the planning document and business requirements specify.
Some questions are particularly effective at revealing missing requirements:
Architectural issues usually don't appear in one PR — they appear as patterns. But the first signal shows up in individual PRs. Catching these early prevents major refactoring later.
@RestController
public class OrderController {
private final OrderRepository orderRepository;
@GetMapping("/orders/{id}")
public Order getOrder(@PathVariable String id) {
// Controller directly calls Repository, skipping Service
return orderRepository.findById(id);
}
}Architecture says: Controller → Service → Repository. When Controllers skip layers, every future addition (caching, transactions, security) requires modifying Controllers too.
// userService.ts
class UserService {
async deleteUser(userId) {
await this.orderService.cancelAllOrders(userId);
await this.userRepository.delete(userId);
}
}
// orderService.ts
class OrderService {
async getOrderWithUser(orderId) {
const user = await this.userService.findById(orderId.userId);
return { order, user };
}
}
UserService knows OrderService. OrderService knows UserService. They're circularly dependent. Unit testing becomes impossible. Deployment is tightly coupled.
Solution: Event-based architecture where UserService publishes UserDeletedEvent and OrderService subscribes.
Discount calculations inside React components. Date formatting repeated across the codebase. Authorization checks in Controllers.
When business logic spreads, it becomes duplication, harder to test, and risky to change.
A business logic bug is code that executes perfectly but does the wrong thing.
function calculateDiscount(subtotal, coupon, member) {
return subtotal - coupon - memberDiscount; // Applies both discounts
}The code looks right. But if your discount policy is "apply the larger discount only, never both," this is wrong.
Verification approach: Plug in numbers and calculate by hand:
Order: $100
Coupon: $10
Member discount: $15
Current code: $100 - $10 - $15 = $75
Policy says: $100 - $15 = $85 (larger discount only)
Now the bug is visible. But you have to know the policy to see it.
To find omissions and business logic errors, reviewers must understand the context before reading code:
Many reviewers skip straight to code. That's when missing requirements slip through.
For complex business logic, developer review might not be sufficient. Include domain experts:
These experts see requirements and edge cases that pure technical code review misses. They catch missing validations, missing notifications, missing compliance checks, and missing business logic.
Good reviewers think about cascading effects. When you deactivate a user account, what else breaks or needs updating?
User deactivated
↓
Subscription needs to cancel (refund policy?)
↓
Active orders need to be canceled (customer notification?)
↓
Team memberships need to be removed (other team members notified?)
↓
API tokens need to be revoked (cached tokens invalidated?)
↓
Shared documents need access revocation (collaborators notified?)
↓
Financial records need to be archived (audit trail preserved?)
↓
Support tickets tied to this user (reassign to another agent?)
A single user deactivation can trigger 7+ systems. Code review only for the immediate user deactivation endpoint misses all of these.
"What happens tomorrow?" A feature works today. What happens when:
"What fails silently?" Problems that don't throw exceptions or show errors:
"Who else cares?" Dependencies on this code:
Before reviewing complex business logic, prepare:
This preparation takes 10-15 minutes but prevents missing requirements that code review alone would catch.
Invisible Problem 1: Incorrect Financial Logic
function calculateDiscount(cartTotal, couponPercent, tierDiscount) {
return cartTotal * (1 - couponPercent) * (1 - tierDiscount);
}
// Code works. But if policy is "apply largest discount only":
// $100 * 0.9 (10% coupon) * 0.95 (5% tier) = $85.50
// Should be $90 (10% is larger)The code is syntactically perfect but semantically wrong. You find it by understanding business rules, not by code inspection.
Invisible Problem 2: Missing Compliance
Code complies with technical standards but breaks regulatory requirements. A PR doesn't mention GDPR requirements, SOX compliance, HIPAA data residency, or PCI DSS encryption. These requirements aren't in code — they're in external documents.
Invisible Problem 3: Broken Workflows
A workflow might be technically correct but missing a step users need. Example: Account deactivation code works, but doesn't notify the user or handle subscriptions. The workflow is incomplete.
AI can't read planning documents. AI doesn't know business policies or regulatory requirements. AI doesn't track what's connected to what in your domain. AI doesn't understand historical decisions or why legacy patterns exist.
These are exactly what experienced human reviewers see and understand.
In your next review, don't stop at "the code works." Ask: "What should happen that isn't in this code?" That question catches missing requirements, missing error handling, missing notifications, missing cascading updates, and missing compliance checks that could become expensive problems later.
The most valuable reviewers aren't the most senior developers — they're the ones who understand the business domain deeply. They know:
This domain expertise is built over time through reviewing many PRs in the same domain. It's irreplaceable and it's what makes experienced reviewers valuable.
Comments
Post a Comment