Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
159726 stories
·
33 followers

Slack is launching collaborative vibe-coding channels

1 Share
An illustration of the Slack logo.

Slack is introducing dedicated channels where teams can vibe-code together with AI agents instead of jumping between different tools and conversations. The Slack Code launch includes open, project-specific code channels with dedicated user tabs, alongside features that compare coding changes and preview HTML output before the project is shipped.

"With Slack Code, when you have an idea or need to build a new feature, update a web page, or fix a bug, you simply tag in a coding agent like Anthropic's Claude or Cognition's Devin, and that agent then spins up a code channel to tackle the task," Slack said in its press release. "There, everyone …

Read the full story at The Verge.

Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Principal Drift in Practice

1 Share

In 2026, the software engineering community is divided by a simple question: Should AI engineers still read the code generated by their agents? One camp argues that code has become virtually free to produce and discard, so humans should focus on systems and guardrails rather than implementation details. The other warns that blindly trusting AI code introduces compounding defects with zero learning, and the result is broken products and frustrated users.

The choice looks binary, but it dissolves once you ask a better question: Which decisions genuinely require human comprehension, and which can be routed to systems inspection?

Through 2024 and 2025, a lot of organizations quietly chose speed over understanding to keep pace with agent output. By 2026 the bill has arrived. Pull requests merged without any human or agentic review are up 31.3%, and for every PR merged, production incidents run at more than three times the rate seen in low AI adoption baselines (Faros AI). CodeRabbit’s analysis found AI-coauthored PRs carry 1.7 times more bugs than human-written code, a Lightrun survey of engineering leaders found 43% of AI-generated changes need debugging in production, and monthly production incidents are up 57.9% year-over-year.

Code quality is the symptom, not the disease. The deeper problem is epistemic agency: knowing what your system is doing and why. Lose that, and you lose the ability to make architectural decisions at all. You become a passenger in a system you built.

Understanding cognitive debt

Cognitive debt is the gap between your system’s complexity and your team’s comprehension of it. Unlike financial debt, which you can pay down, cognitive debt tends only to accumulate. Every quarter you ship faster than you understand, the gap grows a little wider, until eventually it grows wide enough that your team can no longer make safe architectural decisions. At that point you are effectively locked into whatever path the agents chose for you.

It builds through three mechanisms that run in parallel:

  • Vibe coding. You ship a system you don’t fully comprehend, betting that automated checks will catch anything serious. For a quarter or two the bet usually pays off, and velocity metrics climb, but the debt accumulates where nobody’s looking.
  • Compounding complexity. As the system grows, your room to course-correct shrinks. Sonar’s 2026 survey of more than 1,100 developers found that 96% harbor doubts about the reliability of AI-generated code, yet the pressure to ship still outweighs the discipline of careful review. Each quarter that trade repeats, the situation gets harder to reverse.
  • Lock-out risk. When an incident finally demands that you understand a system whose comprehension you handed to an agent, you can’t respond in time. Amazon lived through a version of this in March 2026. Two outages in three days, roughly six hours each, cost millions in lost orders. Public reporting pointed to AI-assisted code shipped without governance checkpoints. A human reviewer might well have caught the blind spot, simply by asking the kind of question an autonomous agent never thinks to ask.

Principal drift, the loss of control, is what the Amazon incident looked like from the outside. Cognitive debt, the loss of understanding, is what made it possible. In high-velocity domains such as financial services, SaaS platforms, and real-time systems, the consequences tend to surface within about six months if nobody is actively governing for them. In slower-moving domains the runway is longer, but the eventual risk is no different. The question worth asking every quarter is whether your team still understands the systems it is shipping.

A framework: Task routing, separation, and embedding techniques

The way out is to route different work to different gates according to actual risk. The same engineer can be a line-by-line reviewer on security-critical work and a systems inspector on utilities.

Full review, where you read every line, is warranted for authentication and security primitives, money movement, permission logic, and destructive data changes. Systems inspection, where you review the design without reading every line, is enough for noncritical utilities, highly decoupled PRs, and changes already protected by robust test harnesses and shadow rollouts. To work out where a given change sits, three questions get you most of the way: Does this PR directly control access, money, or data integrity? Would a bug here cause production downtime lasting more than 15 minutes? Can the change be rolled back without manual intervention? A yes to any of these usually means tier 1. Those thresholds are starting points, not universal law. A real-time trading system might treat one minute of downtime as tier 1, while a batch pipeline could tolerate 16 hours. In financial services “money movement” is unambiguous; in SaaS you’ll have to decide whether code that merely touches authentication, rather than controlling it, belongs in tier 1. Write your thresholds down, revisit them quarterly, and adjust as the systems evolve.

One rule holds regardless of tier: Never let the same agent that authored a change be its only reviewer. Keep the builder and the reviewer separate. An agent that writes code and then validates its own work is a closed loop with no vantage point outside its own reasoning, and a second reviewer, human or agent, brings the outside perspective that catches what the first one can’t see. It has a cost. Two agents roughly doubles the compute, and a human reviewer adds 15 to 30 minutes per PR. On tier 1 code that’s easy to justify. On tier 2 you might reasonably let a single agent build and check its own work, provided you compensate with stronger test coverage. Make the call deliberately and revisit it.

Routing tells you which decisions need a human, but it does nothing to keep that human capable of deciding once the volume climbs. Three techniques help with that, and each addresses a different failure:

  •  Literate code explanations with comprehension checkpoints keep an engineer able to explain a change to themselves and to others. The idea is to have the AI teach rather than merely generate. For a tier 1 PR, ask it to produce a structured explanation that sets the context, spells out the intent, and finishes with a few interactive checkpoints. One engineer’s rule of thumb is not to submit agent-written code to the team until they can pass a five-question quiz on what it does.
  • Ephemeral visualization tools keep an engineer able to predict how a change behaves under load and at the edges. Rather than asking the AI for a prose explanation, ask it to build a throwaway microworld: a visual debugger that traces a gnarly parser step-by-step, or a schema migration rendered as something you can click through. Seeing the behavior tends to stick where reading about it does not.
  • Shared collaborative spaces keep a team able to work at the pace the agents set. Cognitive debt is fundamentally social. Understanding that lives in one person’s head walks out of the door when they do, whereas understanding worked out in the open, in a channel where product managers, engineers, and agents argue things through together, becomes something the whole team owns. Slack, Discord, and Notion all serve; the point is that the mental model gets built in comments and debate rather than in private.

Tier 1 code really does want all three. On tier 2 you can pick and choose. A word on the time estimates in this section: They’re illustrative, drawn from practitioners describing their own workflows rather than from any controlled study, so treat them as order of magnitude rather than gospel. On that basis the three techniques together tend to add something on the order of an hour to a critical PR. When someone objects that there is no time for this, it helps to emphasize the trade you’re making between review time now and incident time later. The later bill tends to arrive with a multiplier attached, paid in postmortems and hotfixes. The teams that have measured it carefully generally find the return turns positive within two or three quarters.

The ground is still shifting. Autonomous loops, where a system discovers a task, plans it, executes it, and evaluates the result without step-by-step direction, are arriving now, and the routing framework and embedding techniques you put in place today are exactly the foundation you’ll run them on.

Operationalizing this: Rolling out over time

This is a CTO or VP of engineering initiative, not something a single team or a lone principal engineer can carry. It needs executive sponsorship, cross-functional buy-in, and real policy behind it. Without that backing, the framework is the first thing waved through the moment a deadline looms.

Sequence matters. Begin by mapping criticality across your tier 1 services: Get architects, team leads, and operations in a room to agree what tier 1 means for you and have one architect write the rubric down afterwards. Budget one to two weeks for a mid-size organization of 50 to 200 engineers, and two to four for something larger. Don’t try to run this alongside a production fire.

Next, fold the three techniques into those high-criticality flows, and resist the urge to blanket every PR at once. Once literate explanations and visualizations are working on tier 1, add builder/reviewer separation on top. When all three have become the default for tier 1 work, spend a quarter watching to confirm that understanding is holding up. A few signals tell you whether it is. If your team needs more than half an hour in an incident review to grasp what happened, comprehension has slipped. If no engineer can talk through the data flow in 10 minutes, it has slipped. If a new hire takes more than a fortnight to get productive on a service, understanding is sitting in too few heads. Pick one or two of these and track them quarter on quarter.

From there, extend the same discipline to tier 2 services, and only then, perhaps 6 to 12 months in, start planning for autonomous loops with real data on what works in your context behind you. The pull toward rolling everything out at once will be strong, but resist it. The organizations that get this right almost never move uniformly; they take one high-risk service, prove the model on it, measure what happened, and only then widen the net. Move too fast and you end up with a framework that reads beautifully in a policy document and quietly falls apart in practice.

None of it works without the surrounding structure. You need a written tier-assessment policy that engineering leadership has actually signed; CI/CD tooling that enforces the rules without anyone having to remember them, whether that is a bot labeling PRs from their changed files and blocking a tier 1 merge that lacks builder/reviewer separation, or a dashboard tracking how many tier 1 PRs went through structured review; incident postmortems honest about when a tier was assessed wrongly; and performance reviews that weight code-quality signals like defect escape rate and incident resolution time as heavily as raw velocity. Absent that scaffolding, the whole thing degrades into good advice that gets ignored under pressure. It needs product leadership onside too. If product can override a tier assessment whenever the ship date gets tight, the framework is already gone, so have that conversation early, before the first crunch rather than during it.

And if you’re reading this already locked in, with a team that no longer understands its own systems, recovery is still possible, though it isn’t free. Treat it as a project rather than business as usual: Put one or two senior engineers on rebuilding understanding full time, accept a pause on new features for the affected systems for two or three quarters, and mine every incident for what it teaches you about the code you inherited. It takes discipline and resourcing, but teams do climb back out.

The question for 2026 was never really whether every engineer should read every line. It’s whether your engineers stay capable of steering the systems they build. Get this right and code still ships quickly, understanding keeps pace, and when something breaks your team can respond because they still grasp the architecture. Task-routed governance is how you buy that: full attention on the decisions that carry real risk, lighter inspection on the ones that simply need to scale. Get it wrong, keep optimizing for speed alone, and the gap widens until steering is no longer an option.


References

The AI Engineering Report 2026: The AI Acceleration Whiplash, Faros AI, faros.ai/blog/ai-acceleration-whiplash-takeaways.

State of AI vs. Human Code Generation Report, CodeRabbit, coderabbit.ai/blog/2025-was-the-year-of-ai-speed-2026-will-be-the-year-of-ai-quality.

State of Code Developer Survey Report, Sonar, sonarsource.com/state-of-code-developer-survey-report.pdf.

Michael Nuñez, “43% of AI-Generated Code Changes Need Debugging in Production,” VentureBeat, venturebeat.com/technology/43-of-ai-generated-code-changes-need-debugging-in-production-survey-finds.

Mark Hull, “What Percentage of AI Code Is Safe in Production?,” Exceeds,  blog.exceeds.ai/acceptable-ai-code-percentage-production.



Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Ready for Go 1.27 on Day One

1 Share

Go 1.27 is here, and the release notes have plenty to explore. Language updates include generic methods, promoted field names in struct composite literals, and improved function type inference. Beyond the language itself, Go 1.27 expands go fix with new modernizers and adds a profile for finding goroutine leaks. These updates touch many parts of everyday development.

GoLand 2026.2 recognizes the new language features in the editor, brings the go fix modernizers into code analysis, and can capture and analyze the new profile in its profiling tools. The GoLand team also added Go 1.27 context to the Modern Go Code Guidelines, so AI coding agents can handle the same language and API changes.

To explore these changes with the Go community, join the Go 1.27 Release Party on August 25, 2026, from 4:00 to 5:30 pm UTC (9:00–10:30 am PDT). The online event will include:

  • An overview of the main changes from the Go development team.
  • Practical demos.
  • Live coding.
  • A look at how GoLand supports Go 1.27.
  • A Q&A session.

Go educator Jesús Espino and GoLand Developer Advocate Ainsley Clark will host the event at The Blue Gopher, an online community space where Go developers can meet, talk, and spend time together.

Explore what’s new in Go 1.27

To help you discover the latest language highlights, GoLand also includes a dedicated What’s New in Go 1.27 page on the Welcome screen. It provides a guided overview of the new language and standard library features so that you can quickly see what has changed since the previous release.

Modernize your code with the official go fix tool

Adopting a new Go release isn’t only about writing new code. Existing codebases can also benefit from improvements in newer versions of the language and its standard library.

Go 1.27 expands the official go fix tool with additional modernizers that help you replace older patterns with their preferred modern equivalents.

GoLand 2026.2 brings these official recommendations directly into the editor.

Running go fix from the command line is useful for updating an entire codebase, but this is usually done separately from your daily coding tasks. You have to run the tool explicitly and then review its changes outside the context where you first encountered the code.

GoLand displays the same modernization opportunities as inspections directly in the editor. You can see why GoLand suggests an update, review it next to the affected code, and apply the corresponding quick-fix without interrupting your workflow.

GoLand supports all go fix modernizers, including those added in Go 1.27:

  • Generic iterator improvements
  • Safer unsafe pointer arithmetic
  • Improved atomic types
  • Embedded composite literals
  • Slice modernizations
  • Other official go fix transformations

After you review an update in one file, GoLand can analyze the rest of the project and collect every applicable modernization in the Problems tool window.

You can review each suggestion, inspect the generated diff, or apply updates across your project in bulk.

In addition, GoLand now lets you enable go fix as a pre-commit check (disabled by default). Before each commit, the IDE runs the official Go modernizers and automatically applies any available updates. This helps teams keep their codebases aligned with the latest Go recommendations as new modernizers become available.

Find goroutine leaks with the new Go 1.27 profile

Concurrency issues are often the hardest performance problems to diagnose. A goroutine may remain permanently blocked long after the original synchronization mistake occurred. This delay makes leaks difficult to identify from the running application alone.

Go 1.27 introduces a new Goroutine leak profile, and GoLand 2026.2 supports it from day one.

The profile reports goroutines that are permanently blocked because the synchronization primitive that they are waiting on, such as a channel, sync.Mutex, or sync.Cond, has become unreachable.

You can capture and analyze goroutine leak profiles alongside CPU, memory, mutex, block, and goroutine profiles directly in the Go Performance Optimization tool window.

The new profiler integrates with the redesigned profiling workflow in GoLand. You can switch between flame graphs, call trees, graph visualizations, and editor gutter annotations to find the source of a leak.

If your application is already running in production, you can import an existing pprof profile into GoLand and jump directly from the captured profile to the corresponding source code.

Help AI write modern Go 1.27 code

AI coding assistants can help you write code faster, but they often lag behind the latest Go releases. Even when they generate correct code, they may rely on outdated idioms or miss newer language features and standard library APIs.

GoLand addresses this with the updated Modern Go Code Guidelines for AI agents.

The guidelines provide supported AI coding agents with additional context about Go 1.27 language features, new standard library APIs, and current best practices. They also take your project’s Go version into account, helping agents generate code that uses features available for the version specified in your go.mod file.

As new Go releases appear, the guidelines are updated to help AI coding agents generate code that follows the latest Go recommendations.

Update to GoLand 2026.2 to use the latest Go 1.27 features from day one. If you’re new to GoLand, start a free trial and explore the full development workflow.

Happy coding!

The GoLand team

Read the whole story
alvinashcraft
3 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

OAuth Identity Chaining, Transaction Tokens, and Human-in-the-Loop: Summer 2026 Identity Standards Recap

1 Share
It might be hard to believe that summer's almost over (though my European colleagues certainly aren't complaining after one of the hottest summers ever), but school schedules and supply lists are here nonetheless. Even as many of us tried to beat the heat and hopefully enjoy a bit of time with our families, several important developments happened in the Identity standards world.
Read the whole story
alvinashcraft
3 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Building an AI-Powered Incident Bot with Octopus Deploy

1 Share

Lately, I caught myself doing the same sequence of actions several times: Prometheus fires an alert (let's say about a pod being in CrashLoopBackOff), I search in the deployment/pod logs, realize that the service has run out of memory, then I open Octopus Deploy, find the right project, then select the environment, bump the resource limit, and finally wait for the rollout to finish and check that the alert has cleared.

The actual fix looks (and it is) pretty straightforward. Most of my time was actually spent context-switching between terminal windows, Kubernetes configs, and Octopus UI tabs. Most routine on-call alerts aren't complex engineering problems. They often involve repeating the same remediation steps from an existing playbook. We usually know what needs to happen, but we end up viewing and manually copying data between monitoring tools, logs, and deployment systems.

This is what made me build a PoC incident bot, which I call Octopus Healer. It’s a service that listens for Kubernetes alerts, passes the pod context to an AI model to suggest a remediation, and maps the output to a predefined Octopus Deploy runbook. Nothing reaches production until an operator reviews and approves the proposed runbook in Slack.

Why Octopus Deploy is the right execution layer

The first design decision was how to handle execution once my preferred AI model suggests a fix. My initial approach while playing with the AI model was to have it generate kubectl commands—or, even better, execute them without manual intervention.

In a real production environment, though, running raw shell commands directly can quickly make things even worse. It can bypass existing approval flows, use overly broad permissions, and target the wrong environment. Instead of playing with fire, I decided to route all execution through Octopus Deploy.

The bot still handles the initial analysis: receiving the alert, collecting the relevant context, and sending the right prompt to the AI model. Octopus then acts as the execution engine, using the permissions, environments, and approval workflows that are already in place. For teams like ours that follow GitOps principles and keep deployment configuration as code, this approach also provides a clean audit trail. Runbook creation, environment selection, approvals, and execution history all remain traceable alongside the rest of the deployment changes.

The full pipeline

Here's how everything connects, from Prometheus alert to Slack notification:

:::figure

:img{ src="/blog/img/ai-powered-incident-bot/pipeline.png" alt="Full pipeline: Prometheus alert to Octopus runbook execution" }

:::

The flow has three phases:

  • Prometheus fires an alert; Alertmanager sends a webhook to the bot, which then fetches the affected pod's logs and any other useful live metrics from the Kubernetes metrics-server (CPU/memory for a CrashLoopBackOff).
  • Once the bot has everything it needs, it sends that context to my favorite AI model, which returns a structured JSON analysis with a remediation type, confidence level, blast-radius classification, and the variable values needed to execute the fix.
  • The bot posts a Slack notification including the root cause and the available action type. The operator reviews the suggested fix, selects the environment, and approves the creation and execution of the runbook in Octopus Deploy. The bot then posts the result back to Slack.

The whole tool is a single stateless service — no database, no message queue. Approvals live in an in-memory store with a 30-minute TTL. If the operator doesn't respond within that window, the approval expires, and the on-call engineer handles it manually.

Giving an AI model the right context

I initially sent far too much context to the model. Most of it was unnecessary, so I reduced the payload to the alert metadata, recent logs, resource configuration, and current resource metrics. The goal was to provide enough information for a useful diagnosis without allowing large log payloads to dominate the prompt and increase the cost.

For each analysis, the bot collects a small but sufficient set of data to share with the AI model:

  1. Basic alert information, including the alert name, namespace, pod, and container.
  2. For the PoC, I limited the payload to the most recent 4 KB. This worked well for the failure cases I tested and prevented large log payloads from dominating the prompt.
  3. Depending on the alert and supported remediation type, the bot may collect additional information. For a pod in CrashLoopBackOff, this includes the configured CPU and memory requests and limits. When available, it also retrieves the pod’s current resource usage through the Kubernetes Metrics API.

The response also needs to be predictable so the service can process it programmatically. The prompt asks the model to return the response in valid JSON only, without an introduction or a Markdown code block, and to use the predefined schema below.

{
  "root_cause": "Clear explanation of the problem",
  "confidence": "HIGH|MEDIUM|LOW",
  "remediation_type": "one of the above types",
  "runbook_params": {
    "namespace": "{{.Namespace}}",
    "deployment": "deployment name",
    "key": "env var name — config_update only",
    "value": "new env var value — config_update only",
    "type": "env or secret — config_update only",
    "container": "container name — image_fix only",
    "registry": "registry URL — image_fix only",
    "image": "image name — image_fix only",
    "tag": "image tag — image_fix only",
    "cpu": "recommended CPU request e.g. 500m — resource_increase only",
    "memory": "recommended memory request e.g. 512Mi — resource_increase only",
    "cpu_limit": "recommended CPU limit e.g. 1000m — resource_increase only",
    "memory_limit": "recommended memory limit e.g. 1Gi — resource_increase only",
    "target_revision": "revision number, 0 for previous — deployment_rollback only"
  },
  "manual_steps": ["any manual verification steps needed"],
  "suggested_blast_radius": "single_pod|single_deployment|multiple_deployments|cluster"
}

The five remediation types the model can choose from and the suggested fix are shown below:

| Type | What it does | | --- | --- | | pod_restart | Rolling restart of the affected deployment | | resource_increase | Scale CPU/memory — For the PoC, the bot uses a simple heuristic based on the currently available resource metrics: 1.5× usage for requests and 2× for limits | | config_update | Patch a misconfigured environment variable or config map entry | | image_fix | Roll forward to a corrected image tag | | deployment_rollback | Roll back to the previous revision with a target-revision override |

For the proof of concept, I've hardcoded the remediation types and suggested fixes to make the development easier. A production version could support a larger catalog of reviewed remediation templates. The model would still select from an allowlisted set rather than generating arbitrary execution logic.

Turning the model’s analysis into a runbook

After validating the model’s JSON response, the bot maps the selected remediation type to an Octopus runbook template. The implementation in this proof of concept is limited but clean: each supported remediation type maps to a predefined template whose script bodies use $(variable) placeholders that are filled with values from two sources — the alert itself (namespace, deployment name) and AI’s model runbook_params. In the example below, the PoC supports only one Octopus runbook step type: kubernetes-script. Future versions could support additional step types provided by Octopus Deploy.

func resourceIncreaseTemplate() *RemediationTemplate {
    return &RemediationTemplate{
        Steps: []RunbookStep{
            {
                Name:     "Update Resource Limits",
                StepType: "kubernetes-script",
                Properties: map[string]string{
                    "scriptBody": "kubectl set resources deployment/$(deployment) -n $(namespace)" +
                        " --requests=cpu=$(cpu),memory=$(memory)" +
                        " --limits=cpu=$(cpu_limit),memory=$(memory_limit)",
                },
            },
            {
                Name:     "Trigger Rollout",
                StepType: "kubernetes-script",
                Properties: map[string]string{
                    "scriptBody": "kubectl rollout restart deployment/$(deployment) -n $(namespace)",
                },
            },
            {
                Name:     "Wait for Rollout",
                StepType: "kubernetes-script",
                Properties: map[string]string{
                    "scriptBody": "kubectl rollout status deployment/$(deployment) -n $(namespace) --timeout=5m",
                },
            },
        },
    }
}

The $(deployment) and $(namespace) placeholders come from the alert. The resource values — $(cpu), $(memory), $(cpu_limit), $(memory_limit) — come straight from the AI model’s response runbook_params. The runbook generator then merges both sources and applies the model's values to the runbook template, returning a ready-to-use runbook. The last part is to talk to the Octopus API to create the live runbook, publish a snapshot and finally execute it in the environment selected by the operator. Each runbook gets a unique, generated name that includes the remediation type, the incident resource, and a timestamp suffix (resource_increase-api-pod-1722687423), so every incident is traceable by type, workload, and time.

A couple of integration details that are worth highlighting are:

  1. Octopus Deploy supports two types of projects, standard and git-backed. This introduces some minor differences at the API level, but the bot handles both project types transparently.
  2. The alert coming from Prometheus and the Octopus Deploy app know nothing about each other, so we need to create a link between the Kubernetes workload and its Octopus project. This can be easily done by adding an annotation on the Deployment as shown below:
metadata:
  annotations:
    octopus.com/project-id: Projects-42

If the annotation is absent, the bot asks the operator to pick a project in Slack rather than failing silently.

:::figure

:img{ src="/blog/img/ai-powered-incident-bot/slack-alert.png" alt="Slack bot asking the operator to pick a project when annotation is absent" }

:::

In production, I would either require the annotation or restrict the Slack picker to an allowlisted set of projects. These defensive fallbacks in the flow can be really helpful sometimes, but I wouldn't rely on them for large-scale systems.

Fully automated or operator-driven?

While building the bot, I kept wondering how far I could take the automation. For local testing, I added an AUTO_APPROVE=true option that skips the Slack interaction and executes the generated runbook directly.

I would not enable that option in production based only on the confidence value returned by the AI model. A model reporting HIGH confidence does not guarantee that its diagnosis is correct or that the proposed action is safe.

For now, the production-oriented workflow keeps the operator involved at three points:

  1. The operator selects the target Octopus environment.
  2. The bot generates the runbook and posts a preview of its steps in Slack.
  3. The operator reviews the proposed actions and either approves or rejects the execution.

Choosing the environment is a separate step because the bot cannot always determine the intended target from the Prometheus alert alone. After the environment is selected, the operator sees the actual runbook steps before anything is executed. This makes the approval more meaningful than simply asking someone to approve a short AI-generated description.

The blast radius is also shown in the approval flow. Instead of relying only on the model to classify it, the bot can derive most of the scope from the selected remediation template and its target. Restarting a single deployment, for example, is clearly different from applying a change across multiple workloads or at the cluster level.

A future version could allow some remediations to run automatically, but only when they pass a deterministic policy. That policy could require:

  • an allowlisted remediation type;
  • a valid annotation linking the workload to a known Octopus project;
  • an environment that can be derived without operator input;
  • a limited blast radius;
  • validated parameters within predefined bounds;
  • and a successful dry run or policy check.

The model’s confidence could still be included as an additional signal, but it should not be the control that authorizes execution.

There is another limitation to the current analysis. The model sees the alert, the pod configuration, recent logs, and current resource metrics, but it does not know everything that happened before the incident.

For example, a pod may start crashing immediately after a configuration change. Based only on the current symptoms, increasing its memory limit might appear reasonable. In reality, the correct action could be to roll back the most recent deployment. The suggestion may appear valid in the context provided to the model, yet be wrong because the important historical context is missing.

This is one of the areas I want to improve next. Adding recent Octopus deployments, configuration changes, image updates, and previous revisions to the diagnostic context would help the model distinguish between a resource problem and an incident caused by a recent change.

Until that context and the deterministic safety checks are in place, keeping an operator in the loop is not just an approval mechanism. It is part of the incident diagnosis. :::figure

:img{ src="/blog/img/ai-powered-incident-bot/slack-update-result.png" alt="Slack bot telling the operator about the Runbook execution outcome" }

:::

After execution begins, the bot continues posting status updates in Slack until the runbook succeeds or fails

What I learned — and what's next

Wiring an LLM into an automated deployment pipeline highlighted a few messy edge cases early on:

In the first version, I let the model generate the full kubectl command. That proved unreliable because in some cases, it returned kubectl flags that did not exist. In other cases, it added Markdown or explanatory text even though the prompt requested only the command.

So I decided to change the design so the model no longer generates executable commands. It now selects one of the supported remediation types and provides only the required parameter values in a predefined JSON format. The bot validates that response and uses those values to fill an existing runbook template. This keeps the model involved in the diagnosis without allowing it to decide exactly which command will run.

Config as Code required more special handling than I expected. Config as Code required more special handling than I expected. Supporting Git-backed projects meant maintaining separate code paths for many API operations. Compound runbook process IDs and Git-reference URL encoding were particularly tedious to debug. The additional complexity is worthwhile for the Git audit trail, but it increased the integration surface considerably.

The in-memory approval store is suitable only for the current PoC. Active approvals currently live in a Go map with a 30-minute TTL. This avoids adding an external dependency in a single-instance deployment, but restarting the pod during an incident removes all pending approvals. This is intentional technical debt for now. A production, highly available version would need shared storage such as Redis or PostgreSQL.

What's next

My immediate priority is finishing HMAC signature validation for incoming Slack webhooks. The signing secret is already parsed, but the request validation itself is not yet implemented, so the current PoC should not be exposed as a production Slack endpoint. After that, I plan to create a Helm chart, add support for more alert types, and include recent deployment history in the diagnostic context. The main lesson from the PoC is that the model should help interpret the incident, not control execution. Keeping the remediation logic in reviewed Octopus runbooks makes the system easier to audit, validate, and operate safely.

Read the whole story
alvinashcraft
3 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

How Code in the Age of Artificial Intelligence Becomes Write-Only and Disposable

1 Share

Artificial intelligence (AI) makes all code write-only,. It’s too dense to read, and tests define the behaviour and become the documentation. Code is also disposable; it becomes easier to rewrite than to debug. Humans can't review AI-generated code at scale. Intent decouples from implementation; developers should focus on creativity.

By Ben Linders
Read the whole story
alvinashcraft
3 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories