M

How I Turned Claude Code + Opus 4.8 into the Best Engineer on My Team

11 min readView source ↗

Cover image

> An engineering deep dive into building an AI teammate, not another coding assistant.

Every Pull Request Creates Future Engineering Work

Every pull request creates future engineering work.

Not because the code is bad, but because shipping software is only the beginning of its lifecycle. Every merge quietly creates future dependency updates, security advisories, flaky CI failures, documentation drift, and dozens of maintenance tasks that don't exist yet. We celebrate shipping features, but we rarely think about the work every release leaves behind.

The strange part is that almost nobody owns it. Teams assign engineers to build systems, ship features, and close milestones, but very few assign someone to continuously own everything those systems will require after they're merged. That was the problem I wanted to solve.

Every Friday ended the same way. I merged a few pull requests, closed my laptop, and considered the week finished. By Monday morning, there were already new dependency releases, CI failures, documentation updates, and security advisories waiting to be investigated. None of those tasks existed when I merged the code. They appeared because the repository kept evolving long after the code had been merged.

For a long time, my workflow never really changed. Every investigation started with a new conversation. I explained the architecture again, pasted logs, linked the same documentation, and reconstructed the same context before any useful work could begin.

I wasn't collaborating with another engineer. I was repeatedly onboarding a new contractor. Every conversation started from zero, even though the repository, the team's practices, and its expectations were largely unchanged. The model wasn't missing context because it lacked capability. It was missing context because I rebuilt the workspace from scratch every single time.

Eventually I stopped asking whether Claude could write better code. I started asking a different question instead: could it own the work every merged pull request inevitably leaves behind?

The Biggest Mistake

The biggest change happened when I stopped thinking about Claude Code as a chatbot and started treating it as an engineering workspace.

A chatbot only knows what exists within the current conversation. A workspace accumulates knowledge, tools, workflows, and conventions over time. That distinction completely changed how I approached the problem.

The architecture looked like this:

Workspace
├── CLAUDE.md
├── Skills
├── MCP Servers
├── GitHub Actions
└── Opus 4.8

At first glance, none of these components seems particularly remarkable. Repository instructions have existed for years. External tools aren't new, and GitHub Actions have been around forever. The interesting part isn't the individual pieces. It's how they reinforce one another.

Each component removes a different kind of repetitive work. Together, they create an environment where another engineer can understand the repository, investigate problems, and make informed decisions without starting from scratch every time. That became the goal. I wasn't trying to build a better coding assistant. I was trying to create an environment where another engineer could do their job.

Repository Memory with CLAUDE.md

The first problem was persistent knowledge.

Every experienced engineer develops an understanding of the repository that rarely gets written down. Architectural decisions, deployment expectations, coding conventions, release procedures, and operational habits gradually become shared knowledge within the team. New conversations lose all of that context unless someone explains it again.

Claude Code solves this with CLAUDE.md.

Instead of embedding repository knowledge into prompts, I moved it into the repository itself. The file became persistent context that evolved with the codebase.

CLAUDE.md
├── Architecture
├── Development Workflow
├── Coding Standards
├── Testing Strategy
└── Release Process

Now every conversation started from the same foundation. Claude already understood how the repository was organized, how the team worked, and which conventions mattered before any investigation began. Updating the development process became as simple as updating a version-controlled document.

The repository was no longer the missing piece. The rest of the work happened outside it.

Engineering Happens Outside the Repository

Most software work depends on systems outside the repository.

Pull requests, CI pipelines, workflow runs, issue trackers, deployment platforms, release notes, and monitoring systems all contain information essential to making good decisions. Reading source code alone is rarely enough to understand what's actually happening.

That's where MCP changed the workflow. Rather than copying logs, links, or pull request discussions into every conversation, Claude could retrieve the information directly from the systems engineers already use every day. The important part wasn't the protocol itself, but eliminating the manual work required to gather context before an investigation could even begin.

A typical investigation might use tools like these:

github.list_pull_requests()

github.get_pull_request()

github.get_workflow_runs()

github.search_code()

Instead of asking me for screenshots or links, the workspace could inspect pull requests, review workflow failures, search the repository, and collect the evidence required to understand the problem. My role gradually shifted from assembling context to reviewing conclusions.

By this point, the workspace understood the repository and knew where to find information.

It still didn't know how our team investigated problems.

Teaching Engineering Work

Every engineering team develops processes that exist almost entirely in people's heads.

Ask two senior engineers to review a dependency update or investigate a flaky CI failure, and they'll usually follow similar steps. They gather context, check previous incidents, evaluate tradeoffs, review release notes, and only then decide whether any action is necessary. Those workflows are learned through experience, but they're rarely documented in a way another engineer can execute consistently.

Anthropic introduced Skills to solve exactly this kind of problem. A Skill packages domain knowledge into a reusable workflow that Claude can invoke whenever a particular type of problem appears. Instead of repeating instructions in prompts, the investigation process becomes a permanent part of the workspace.

A typical repository might look like this:

skills/
├── python/
│   ├── SKILL.md
│   └── ...
├── code-review/
│   ├── SKILL.md
│   └── ...
└── ...

Those built-in Skills were a useful starting point, but most of the work I cared about wasn't language-specific. It was repository maintenance.

Over time I added Skills like these:

skills/
├── dependency-review/
├── flaky-ci/
├── release-check/
├── security-advisory/
└── documentation-drift/

Each Skill existed for the same reason. Somebody had merged code months earlier. Dependencies continued evolving. Documentation drifted away from reality. CI pipelines became less reliable. New security advisories appeared long after the original implementation was finished. None of that work existed when the pull request was merged, but all of it eventually required someone's attention.

The purpose of a Skill wasn't to generate code. It was to capture an engineering playbook.

A dependency review, for example, wasn't simply "update packages." The Skill reviewed release notes, checked for breaking changes, evaluated security fixes, looked for known issues, and determined whether the update was worth making. Sometimes the correct outcome was a pull request. Sometimes it was a recommendation to wait.

The goal was never code generation. The goal was an engineering decision.

Why Opus 4.8 Changed the Workflow

The biggest difference came from Opus 4.8.

It wasn't simply that the model became smarter. The investigations became noticeably more disciplined. Instead of jumping to the first plausible answer, it gathered evidence from multiple sources, revisited earlier assumptions, and cross-checked its findings before reaching a conclusion.

That behavior mattered because investigations are rarely linear. A failed workflow might point to infrastructure instead of application code. A dependency update might uncover an unrelated compatibility issue. The first explanation often isn't the right one, and experienced engineers know that premature conclusions usually create more work later.

As the reasoning improved, I found myself evaluating the process differently. I stopped asking whether the answer looked convincing. I started asking whether the investigation followed the same process I would expect from another experienced engineer.

That turned out to be a much higher standard.

The Wrong Abstraction

The biggest mistake wasn't treating Claude like a chatbot.

It was treating engineering as a collection of independent tasks.

For years, that's how I described maintenance work to myself. Review this dependency. Investigate this failed workflow. Prepare this release. Each request sounded like an isolated task, even though they were all symptoms of the same underlying responsibility.

Experienced engineers don't wake up looking for random tasks to complete. They own systems, and tasks emerge naturally from that ownership. Once I realized I was teaching tasks instead of responsibility, the rest of the architecture became much simpler.

From Tasks to Responsibilities

That realization completely changed how I wrote prompts.

Instead of saying:

> Update this dependency.

The responsibility became:

> Review the repository and determine whether any dependency deserves attention.

Instead of saying:

> Investigate this failed workflow.

The responsibility became:

> Determine whether this failure indicates a larger reliability problem.

Those sound similar, but they produce very different behavior. A task assumes the work already exists. A responsibility first decides whether work exists at all.

That distinction became surprisingly important. Sometimes the correct outcome was a pull request. Sometimes it was a report explaining why nothing should change. Experienced engineers create value by deciding when code should not be written, and I wanted the system to make that decision as naturally as it generated new code.

By this point, I wasn't trying to automate repository maintenance anymore. I was trying to give someone ownership of the maintenance every repository inevitably accumulates. That realization changed how I thought about the entire workflow.

I stopped assigning tasks. I started delegating responsibilities.

Running the System

Once every piece was in place, the individual components stopped feeling important.

What mattered was how they worked together. None of them solved the maintenance problem alone. Together, they formed a system capable of owning work that would otherwise accumulate in the background.

The workflow itself was surprisingly straightforward.

GitHub Actions
        ↓
Repository Context (CLAUDE.md)
        ↓
MCP Tools
        ↓
Relevant Skill
        ↓
Opus 4.8 Investigation
        ↓
PR, Report, or No Action

Some of this work started automatically through GitHub Actions. Anthropic’s own Claude Code Action follows the same idea. A workflow can invoke Claude with the repository context already available, allowing recurring maintenance to happen without someone opening a new conversation every week.

A scheduled workflow can be as simple as this:

on:
  schedule:
    - cron: "0 8 * * 1"

The schedule isn’t the interesting part. What matters is everything that happens after it starts.

The workspace already understands the repository through CLAUDE.md. Through MCP, it can access GitHub and other systems, select the appropriate Skill, gather evidence, investigate the problem, and decide whether anything actually deserves attention. By the time I review the results, most of the routine investigation has already happened.

Most runs don’t produce a pull request. That isn’t a failure. It’s often the correct decision.

Good engineers don’t create work simply because someone asked them to investigate. They confirm that an update can wait, determine that a failing workflow was transient, or explain why a security advisory doesn’t affect the repository. Eliminating unnecessary work is just as valuable as producing new code.

Those reports gradually became as valuable as the pull requests themselves. They reduced uncertainty without increasing maintenance, which meant the system wasn’t simply generating changes. It was reducing the amount of work that actually needed to happen.

Eventually I noticed something unexpected.

I wasn’t spending less time writing code. I was spending less time discovering the work that needed to be done.

The routine investigation had already happened. The evidence had already been collected. The recommendation had already been documented. My role shifted from gathering information to reviewing conclusions, which turned out to be a much better use of my time.

The System Matters More Than Any Individual Component

Looking back, I don’t think the result came from any single component.

CLAUDE.md gave the workspace persistent knowledge of the repository. MCP connected it to the systems engineers already use every day. Skills captured repeatable processes. GitHub Actions turned recurring work into recurring responsibility. Opus 4.8 provided the reasoning that tied everything together.

None of those pieces would have solved the problem on their own. Together, they stopped feeling like a coding assistant and started feeling like another engineer.

Conclusion

Every pull request leaves something behind.

Sometimes it’s a dependency that will need updating six months later. Sometimes it’s documentation that slowly drifts away from reality. Sometimes it’s a security advisory that doesn’t exist yet. Sometimes it’s a CI failure waiting for the right combination of changes to appear.

That work exists whether anyone owns it or not.

For years, I treated it as an endless stream of small tasks. Open a new conversation. Rebuild the context. Gather logs. Investigate. Repeat. I assumed the maintenance itself was the problem when the real problem was that every investigation started from zero.

Building this system didn’t eliminate maintenance. It gave that maintenance an owner.

I don’t think I built a better coding assistant. I think I built a system that owns the engineering work every merged pull request leaves behind.

Related articles