Coding Agents & Workflows A developer outlines a workflow for using coding agents like Claude Code and GitHub Copilot, emphasizing the need for tailored skills and context management to avoid unsafe code generation. The post demonstrates how a checkout skill enforcing distributed saga patterns prevents issues like direct inventory deduction and broken state machines. If you're working with coding agents like Claude Code, GitHub Copilot, or any other AI assistant, you've probably noticed something: they can generate code faster than you can review it. This creates a new set of challenges that traditional development workflows weren't designed to handle. Here is what I believe will help you. BTW before reading this post try to: Keep that branch around, once you've read the post, you'll go back and redo the same task with the principles below applied, so you can compare the two results yourself. Your choice of tools depends on your experience level, and that choice shapes the whole workflow you're about to build: Whichever you pick, you need to learn to be patient with LLMs. They usually tend to generate a ton of text, and rushing past it defeats the point of reviewing it at all. When you code, you have a ton of context in your head. So if you are expecting a coding agent to deliver good results you need to give it enough context but beware of context dilution https://diffray.ai/blog/context-dilution/ . ⚠️ WarningIf you install superpowers plugin get ready for it to spin up subagents and burn a ton of tokens in the process. Personally I downloaded their brainstorming, and systematic-debugging skill and removed the plugin. Consider using MCP servers like Contact7 https://context7mcp.com/claude/ if they offer exactly what you need. Some plugins may already cover the same functionality, so try to avoid overlap. Commit them to git so everyone has access. 💡 Pro TipInstall Context7, it is so useful since LLMs do not have always the latest documentations for a library. You can enforce it by adding a .mcp.json : { "mcpServers": { "context7": { "command": "npx", "args": "-y", "@upstash/context7-mcp@latest" } } } Rather than relying on general knowledge, develop skills tailored to your project. Imagine you are building the backend checkout service for a massive e-commerce platform think Shopify, Amazon, or a large retail enterprise . This service handles: Now an engineer on your team asks the coding agent to: We are releasing a 'Flash Sale' feature tomorrow. We need a new endpoint that accepts a list of product IDs and quantities, bypasses the user's shopping cart, and goes straight to the checkout/payment page. Ensure it validates the flash sale time window." What happens WITHOUT a skill: the agent reads the prompt, sees "bypass cart" and "straight to payment" , and happily writes something like this LLMs try to follow your instructions as much as possible : python @app.post "/flash-checkout" def flash checkout products, user id : total = 0 for p in products: 🚨 UNSAFE: Direct DB hit. Inventory is immediately deducted, even if the user's credit card fails loss of stock . db.inventory.update one {" id": p.id}, {"$inc": {"stock": -p.qty}} total += p.price p.qty 🚨 WRONG: Hardcodes US tax, ignores EU and other regions This is a contrived example and most top LLMs would ask you about it total = 1.08 🚨 BREAKS STATE MACHINE: Direct status update State machine is broken, so the shipping service never picks it up. db.orders.insert one {"user": user id, "status": "COMPLETED", "total": total} 🚨 NO IDEMPOTENCY: User double-clicking charges them twice stripe.charge amount=total return {"success": True} Now imagine what would have happened if you had a skill like this in .claude/skills/checkout-orchestration-skill/SKILL.md : --- name: checkout-orchestration-skill description: 'Enforces the distributed saga pattern for the e-commerce checkout pipeline. Use this skill whenever implementing or modifying order placement, payment flows, or cart finalization. It mandates idempotency Redis , inventory reservation never direct deduction , strict order state machine transitions OrderStateMachine , tax aggregation TaxJar/Vertex routing , async fraud handling 800ms timeout , and Kafka event emission order placed topic for eventual consistency.' --- Core Architectural Rules NEVER treat checkout as a single CRUD update. It is a distributed saga . 1. Idempotency First : Every checkout request must include an idempotency key . If the key exists in Redis, return the cached result immediately. 2. Reserve, Do Not Deduct : Never write directly to inventory table. Always call InventoryReservationService.reserve which holds stock for 15 minutes timeout period . Only finalize deduction after PAYMENT CONFIRMED event. 3. State Machine Only : The Order entity has a strict state machine: PENDING - FRAUD CHECK - AUTHORIZED - PAYMENT CAPTURED - FULFILLMENT QUEUE Never skip states. Never manually set order.status = 'completed' . Use OrderStateMachine.transition 'CAPTURE' . 4. Tax Agnosticism : We use TaxJar for US/CA, and Vertex for EU. Always call TaxAggregator.get tax which handles the routing under the hood. Do NOT hardcode tax rates. 5. Fraud Timeout : The fraud check is async. If it takes 800ms, we proceed with FRAUD PENDING status and place a dead-letter retry, but we do NOT block the user. 6. Eventual Consistency : After capturing payment, push exactly one event to the order placed Kafka topic. Must include the correlation id for tracing. And now if you send the same prompt to the coding agent, it generates real, production-grade, domain-aware code: python @app.post "/flash-checkout" def flash checkout products, user id, idempotency key : 1. Enforce Idempotency cached = redis.get idempotency key if cached: return cached 2. Validate Flash Sale window domain logic if not timezone.now in flash sale window: raise HTTPException 400, "Flash sale not active" 3. Build line items line items = LineItem p.id, p.qty for p in products 4. Reserve inventory using the domain service DOES NOT deduct yet reservation ids = InventoryReservationService.reserve bulk line items 5. Get tax through the aggregator handles US/EU routing tax = TaxAggregator.get tax line items, user id 6. Initiate state machine order = OrderStateMachine.create user id=user id, line items=line items, tax=tax, status="PENDING" 7. Fraud check async, non-blocking fraud score = FraudScorer.submit async order.id 8. Authorization not capture, just auth to check funds auth token = PaymentGateway.authorize order.total, user.payment method 9. Transition to authorized state OrderStateMachine.transition order.id, "AUTHORIZE", context={"auth token": auth token} 10. Emit Kafka event for downstream processing event bus.publish "order placed", { "order id": order.id, "correlation id": request.headers "X-Correlation-ID" } response = {"order id": order.id, "status": "AUTHORIZED"} redis.setex idempotency key, 3600, json.dumps response return response You can e.g. create a command for labeling GitHub issues: mkdir -p .claude/commands cat .claude/commands/label-github-issue.md << 'EOF' --- description: Fetch a GitHub issue and apply appropriate labels using gh argument-hint: