5-Minute DevOps: AI is Taking Our Jobs!! Pt. 2
In February 2024, I wrote about my journey from “AI coding is BS” to realizing “I’d better learn how to do this if I want to stay relevant.” Since then, AI-assisted development has matured quickly. Tools are more capable, patterns for using them are emerging, and — predictably — some people are drawing the wrong lessons.
Some things have not changed over the past two years. The nay-sayers are saying “nay” even more vociferously with even worse arguments, usually philosophical rather than engineering. I’m sure the job market will sort that out. Survival is optional when you don’t consider learning to be a requirement. I’ve been using more machine-generated code, doing more machine-executed refactoring, and learning from pain what not to do.
In my previous article, I predicted that Behavior-Driven Development and the skill of defining business features as acceptance tests would become more critical for developers in the coming years. Recently, I wanted to see how far I could push building something with nothing but acceptance tests. It went really well.
I have a problem. I have years of content on Medium that I’d like to make more portable. I want to extract my Medium blogs in markdown with frontmatter metadata so that I can also post them elsewhere, use them as content for a self-hosted blog, or even train a model on the content. Medium won’t let you do that through an API, the RSS feed is only good for the last 20 posts, and the download you can request seems designed to thwart reusability. That leaves screen scraping. So, let’s build a tool.
Using ATDD with Claude
We needed an overall plan that we could implement in small steps, along with defined outcomes. I could have spent time writing the behavior tests myself, but I was curious about what would happen if I asked Claude to create the behaviors. Here's my initial prompt to Claude.
I want to create an application that will scan all of my published blogs on medium.com and download them as markdown
with frontmatter. Medium does not provide an API to do this. Their RSS feed only shows the last 20 posts, but I need all
of the posts. I cannot use a chrome plugin. Medium requires a user to be logged in to see content and uses Google's SSO,
so the tool should allow me to login with my google credentials.
Technical constraints:
We should use vanilla JS with es modules, functional programming, and arrow functions.
Create a prompt and feature file to use with Claude Code
I want claude code reference the feature file and use acceptance test driven development.
It should use eslint and prettier and should fix any linting and style issues after each test passes.w
```text
After a few seconds, Claude generated a [file that defines the working rules](https://github.com/bdfinst/medium-download/blob/2196bf34df081aeb19d83010619552078afae5d4/CLAUDE.md) (TDD, functional programming, etc.), a file for [instructions for setting up the project](https://github.com/bdfinst/medium-download/blob/2196bf34df081aeb19d83010619552078afae5d4/SETUP.md), and [a feature file for the features Claude suggested](https://github.com/bdfinst/medium-download/blob/2196bf34df081aeb19d83010619552078afae5d4/features/medium-scraper.feature).
After reviewing the working instructions, I wanted to emphasize more clearly that quality processes were not optional. I’ve seen Claude “forget” those when not instructed otherwise. I ended up with these instructions.
Next, I reviewed the [generated feature file](https://github.com/bdfinst/medium-download/blob/2196bf34df081aeb19d83010619552078afae5d4/features/medium-scraper.feature). This was quite good. In fact, I only requested changes after I had an MVP and could play with the results
### Set Course and Engage
For this, the prompt was simple:
```text
Setup the project and implement the first scenario
```text
Then I watched the agent work, reviewing and approving the steps as needed, while sipping my coffee and responding to LinkedIn comments. Once each scenario was complete, I manually validated it. For example, once the Google login feature passed tests, I tried logging in. It worked on the first try.
#### Discovery and Problem Solving
When we started on the next scenario, *Discover All Published Posts*, we hit our first issues. Since I didn’t define clearly how to identify a post URL, Claude identified every link on the profile page as a blog post. So, I provided an example blog URL, it updated its search logic, and the irrelevant links were filtered out. Now it was finding 3 of my 70+ posts. Well, that’s a start. It turns out that Medium uses an infinite scroll to display the blogs, so we need to navigate that.
I’ve no personal experience scraping a webpage that uses infinite scroll (my primary skill is backend), but I know it’s a solved problem in the world, so I tried the simplest thing. I updated the scenario with:
```text
And it should handle pagination or infinite scroll to load all posts
```text
That change resulted in finding more, but not all of my posts. Hmmm.
Next, I discovered that the URL for posts sent to publications can have a few different formats and are different from the pattern for non-publication posts. So, with some more prompting to add those formats to the tests, we had a more complete scenario:
```text
Scenario: Handle Posts Submitted to Publications
Given I have published posts both on my profile and to Medium publications
When I navigate to my Medium profile page
Then the scraper should identify posts on my profile with URLs like:
| URL Format | Description |
| https://username.medium.com/post-title-123 | Personal profile posts |
| https://medium.com/@username/post-title-456 | Personal profile posts |
And the scraper should also identify posts submitted to publications with URLs like:
| URL Format | Description |
| https://publication-name.com/post-title-789 | Custom publication domain |
| https://medium.com/publication-name/post-title-abc | Medium-hosted publication |
And all posts should be attributed to the correct author
And publication information should be captured in metadata
When I process publication posts
Then the scraper should extract content from the publication URL
And it should preserve the original publication context
And it should include publication name in the frontmatter metadata
```text
After this, everything else was straightforward. We implemented each scenario, always starting with a failing acceptance test. After I had a passing scenario, I committed the change and went to the next. Lather, rinse, repeat until I had ***enough*** functionality for my purposes.
If you compare the [original acceptance tests](https://github.com/bdfinst/medium-download/blob/2196bf34df081aeb19d83010619552078afae5d4/features/medium-scraper.feature) to the [version in the last commit](https://github.com/bdfinst/medium-download/blob/master/features/medium-scraper.feature), you’ll see the plan changed as more was learned about the problem. Every change was small and focused on solving the next small problem. In fact, not all scenarios were implemented because I stopped when the feature set met the need. It was interesting, though, that Claude suggested features to deliver a more robust solution. Things like restarting a download that failed in the middle, rate limit handling, and incremental updates. I didn’t ask for those, and I don’t need them today, but this was not the first time that Claude has suggested useful improvements.
All in, this took about four hours, starting with my first prompt.
### Learning the Wrong Lessons
In the above example, I used a disciplined approach to rapid development. I knew what my goals were, I had an idea about how to get there, and I worked in small steps to achieve my goal. I spent about 15 minutes planning and a few hours guiding the agent through my features with tests, learning as I went. This is no different than how I would work with a human team. However, anti-patterns are emerging that are driven by the same misunderstanding that is rampant in the industry: people believe the work of a developer is to write code.
#### Vibe Coding
Vibe coding hasn’t stabilized as a definition yet. Some use it as a pejorative, and others use it to mean a new form of sustainable software development. However, the most common understanding of the term “vibe coding” is “tell the bot what you want and run what it builds.” With the current generation of tools, you can rapidly prototype something that looks useful and seems to work in just a few days this way. However, putting that solution into production and making it critical to the mission is the same mistake people have been making forever with POCs. Someone has a “brilliant” idea, they build a proof of concept rapidly without standard quality processes, there’s a business decision to go forward, and instead of keeping the lessons from the POC and throwing away the code, they deploy mountains of tech debt into production, bury themselves in operational issues, and then try to fix it while also adding features to the garbage they built. I’m not a fan.
There is far more to delivering reliable software than writing code. For example:
> “Replit deleted my database and lied!”

If we were to do a postmortem on this, the conclusion I would come to would not be “Replit did the wrong thing.” The CORRECT lesson that should drive their improvement process is “we gave Replit production access with no pipeline to validate changes.” Also, “we did not have a process for backing up critical data.”
> “The AI made a change and deleted months of my code! How do I get it back?”
This is also becoming a complaint we are seeing more often on social media. When you make it easy to build things that require no knowledge of the fundamentals, like ***version control***, people will get burned.
These examples highlight an important point: AI is not less error-prone than humans. It’s important we have the quality processes in place (test-driven development, work in small batches, rapid feedback) to catch errors before they become incidents.
Vibe coding makes it faster and cheaper to increase operational expenses. No matter how fast or how inexpensively we can generate code, the work is and has always been delivering sustainable solutions, not code. Establishing and maintaining a solid quality process, including the quality of the information about the features, has always been fundamental to the work. Many organizations are behind the curve on software quality processes and have created entire QA organizations focused on testing after development to try to “inspect quality in at the end.” I suppose one of the advantages of machine-generated code is that, like anything else that accelerates feedback, it highlights the gaps in our processes when things begin to break. Quality is a process, not a step.
#### Waterfall is the Best Way
I recently came across someone who claimed that waterfall project management is the best way to work with AI. Define all the requirements upfront, and the AI will generate the working code. We can then test the output against these requirements. Simple! Machines writing code do not change the fundamental problems we face when developing new products:
- The requirements do not match the users’ needs
- They will be misunderstood during development
- The need will change before we deliver
The only solution is to deliver in small steps and get feedback as rapidly as possible. AI-assisted development helps us accelerate the feedback loop. It in no way replaces the need for feedback.
### The Right Lessons
The techniques I used for this example are exactly the same techniques I had to learn to be effective at continuous delivery. I used BDD to define the acceptance criteria. This provided the information I needed to code acceptance tests and then write code to make the tests pass. Continuous integration requires that we only commit tested code, and BDD with ATDD makes this much easier. I worked in small steps, validating each one as I went to confirm or adjust the plan. When I had a small step working, I committed the change to prevent the next step from breaking something. Early on, I thought there would be new patterns to learn. It turns out that the best pattern to use with AI is continuous delivery.
More people are coming to the same conclusion that you can get really good outcomes from AI assistants when you pair them with modern software engineering methods like XP and continuous delivery. The opposite is also very true.
I’ve seen many developers complaining that AI is either no help at all or worse than useless. However, I’ve yet to hear about someone skilled at XP struggling to use the tools effectively. There appears to be a strong correlation between knowledge of modern software engineering practices and positive outcomes with AI. If you get bad outcomes, you’re probably bad at the fundamentals. Griping about it is only telling on yourself.
The optimist in me hopes that the pressure to stay relevant will drive more people to finally stop arguing about practices like test-driven development and continuous integration and will decide to level up instead. The pessimist in me predicts people will learn the wrong lessons, and we’ll see more dramatic incidents in the future. Time will tell.
### Next Steps
**The tools will keep evolving, but the fundamentals of engineering won’t.** My experiment showed me that AI can accelerate development dramatically — *if* you pair it with practices like ATDD, CI, and small, validated steps. Without those, you don’t get productivity; you just get faster paths to failure.
That’s the lesson many are missing. AI doesn’t replace the need for software engineering discipline; it makes it more necessary than ever. The people getting the best outcomes with AI aren’t the ones writing the flashiest prompts — they’re the ones already skilled in modern practices like XP and continuous delivery. I suggest starting by learning more about the workflow of continuous delivery, starting with Behavior Driven Development. Practice driving your code with tests before adding a robot into the mix.
If you want to thrive in the AI era, don’t start by asking, *“How do I prompt better?”* Start by asking, *“How do I deliver software better?”* AI is an amplifier. Whether it amplifies your discipline or your dysfunction is entirely up to you.
### References
- [MinimumCD.org](https://minimumcd.org/)
- [Modern Software Engineering — Dave Farley](https://www.davefarley.net/?p=352)
- [eXtreme Programming Explained — Kent Beck](https://www.oreilly.com/library/view/extreme-programming-explained/0201616416/)