$ cd ..
// compiling-in-your-standards.md

Reducing the cost of the Nth to as near zero as possible

codingdotnetcraft

200’ deep in Lake Michigan with 2 hours of decompression ahead of you or 5,000 feet back in a flooded mine is no place to have your equipment or your training fail you. It’s inevitable though - eventually equipment fails and eventually mistakes are made. In diving, we review everyone’s mistakes and it isn’t to shame them - it’s because the information that comes from it is valuable. Every mistake is an opportunity to examine your tools and your practices for improvement. You tend to become a tad hyper-obsessive about eliminating inefficiencies or opportunities for mistakes when you’re involved in activities like these. Whether this part of my personality comes from my diving or if I was drawn to that kind of diving because of my personality is a question for another time.

I throw around some fairly bombastic claims, and I commit myself and my teams to things that look reckless on the surface. I wanted to show why in my mind it’s the polar opposite of that. The reason I am able to make the bombastic claims that I do and the reason I am able to be so glib about being able to integrate anything is that I’ve been exposed to & incorporated techniques into my way of working that allow me to be so. These tools and techniques have instilled a deep sense of confidence in me that I can do these things easily, because I have over and over again with them or with tools similar to them.

The best part about all this way of working? It’s 100% choose your own adventure and free to adopt - the tooling is 100% open source and you can use this just as easily in your home Docker lab or AWS as you can Azure for your deploy target. Everything I do here is optional, interchangeable and configurable. It meets you where you are, allows you to meet your org where it is, meets your colleagues where they are and allows you to meet your integration partners where they are. AWS instead of Azure, Python instead of C#, X instead of Y, I want to add approval gates at point Z? Supported, anticipated and already has the hooks and adapters to support it. That’s the point.

This isn’t being glib or careless. This is pattern recognition and engineering as a craft.

I’m using this reference repo I put together as my anchor throughout this article - jasondostal/dotnet-api-platform.

The central thesis of this repo, if I can be so bold and pretentious to use that term, is that your preferences, policies, standards and patterns of working with software throughout every stage of your software development life cycle don’t live in a Wiki or a prompt template. Compliance changes from something you hope all the humans & agents adhere to, to hard checks that fail your builds.

These development practices are things that have made me successful, that I have found incredibly useful for my way of working. You likely have different preferences and are working on different types of problems than I am and so these may not apply. I learned by picking up things from others and adapting them to my situations so this is the spirit in which I’m sharing this.

This repository is both a deployable integration platform and a set of tools that help me deterministically develop software to tight standards. Every bit of the architecture of the application and tool chain is built to not only allow requirements to chain throughout the system but it enforces it. It makes it hard not to adhere to your standards once you start working in this pattern because it’s just so easy.

And THAT dear reader is the unlock to all this. How do you code with LLMs effectively? How do you know that your agents are writing code that adheres to your structural guideline? How can you be sure that the agents are writing the appropriate logging into your app without checking every line? By embedding as much of it as you can in structural checks and controls rather than verbal intent in a prompt.

It’s not all about control either though! The control is one aspect, and at a certain point - unfortunately - when you work in software development at large organizations or in regulated industries the control can sometimes seem like the only thing anyone focuses on. My approach to it is to embrace it - clear standards and policies help accelerate development because if everyone is on the same page about them, you have opportunities to integrate it & automate it in your workflow.

In diving, you ruthlessly evaluate your tools. If you are going to bring something with you on cave dive, it has to earn it’s keep. It has to serve a purpose. And if it’s valuable enough to have earned a spot in your kit then you need to bring a backup or have another way to accomplish the same outcome with a different tool. You have to be prepared for virtually anything.

I tend to approach my software development the same way. I lean towards pluggable tools, kinda like *nix commands. Simple little things that you chain together to do larger things. And I firmly believe that you can build up a set of tools and practices that can allow you to integrate with anything. And I even more firmly believe that anyone can learn how to do these things this confidently.

The app is a collection of tools in the Azure ecosystem. It translates to others just as well - containers, queues, busses, eventing, messaging, lightweight DBs, serverless functions, pipelines and the like. It allows you to take data in any format, do anything with it and output it on the other side. JSON, XML, SOAP, PDFs, CSVs, skewed JPG scans. Legitimately, you can plumb in Azure’s Vision Service to an automated pipeline that scans JPGs to standardized records you can pump into an event bus that drives…<insert wild idea here>. It can drive whatever you think up - an alert, an email, a database write. Or you can send it to a queue that fans out to all 6 and publishes an event stream that anyone else can listen to because hey maybe someday it would be fun to have a sparkline pulsing on your homepage showing how frequently X is happening.

Or you could have your coding LLM turn your kitchen lights blue whenever it’s ready for you to review it’s work. Or you can put a wireless magnetic sensor on your chipmunk trap and get an alert on your phone whenever you get one of the squeakers.

As an enterprise architect, how do I know that if I set a policy that every customer record access has to be logged that it is across every application? Because every app inherits the policy in a runtime, and the build pipeline fails anything that doesn’t. Architecture tests fail builds if anything tries to route around it.

How do I ensure a standard propagates down to 200 other repos and projects worked on by LLMs and people? Pipeline templates, platform packages, analyzer configs all live in one spot while pipeline & architecture checks enforce it. If external auditors suggest a change in data masking policy, a bump to a shared package is all it takes for everything to get consistent.

As a developer, how do I set up a new API or a new app to work with this vendor we just signed a contract with? A single TypeSpec .tsp, a quick adapter that maps the vendor to our shape and a line of code to register it and boom - audit policy, pii masking, tracing, performance monitoring, authentication scopes - done.

As an information security engineer, how do I ensure the our secure coding policy is being followed? Any practice outside of standard fails a build, a test or places a block. Code that tries to hit source systems outside of the audited path fails to even compile.

This sort of framework, to me, gives me the opportunity to work on the interesting and the unique problems. I don’t want to write logging operations on every new project or have to hand wire performance monitoring code on every project. I want to work on and code my project. These things and these tools get me there faster. Maybe they’ll help you too.

Resources

Tools or techniques I’ve found useful

ToolWhat it does
TypeSpecAPI design language; one source compiles to OpenAPI, JSON Schema, etc
OpenAPIContract everything is generated from or checked against
JSON SchemaSchema for canonical models
SpectralLints contracts against your style guide — style prefs as CI gate
Redocly CLIBuilds dev portal docs via pipeline
SchemathesisConformance testing — proves the running API matches spec.
PrismMock server from the OpenAPI — test before implementing
Roslyn analyzersRules as code.
NetArchTestArchitecture/dependency boundaries as unit tests
ArchUnitNETAdditional arch checker
BannedApiAnalyzersMore rule enforcement
EditorConfigStyle prefs
gitleaksScan for committed secrets.
.NET AspireSuper lightweight orchestration, lots of intriguing possibilities
OpenTelemetryDelicious observability
Central Package ManagementKills cross project drift dead
Native AOTSmall fast binaries
HTTP Resilience (Polly)Retries and circuit breakers
Castle Core (DynamicProxy)Hook/audit alllllll the things
Audit.NETMore auditing logging, diffs, EF ops
xUnitTesting
WebApplicationFactoryIntegration testing
Testcontainers for .NETMore testing
VerifyMOAR TESTING
Anti-Corruption LayerVendor whatever mapped into your contracts
Hexagonal / Ports & AdaptersSeparation, pluggable adapters
RFC 9457 Problem DetailsOne set of errors
Model Context Protocol (MCP)Tools for agents
Team TopologiesWork process