My organisation recently underwent a major restructuring. In a matter of weeks, my team doubled in size and multiplied its responsibilities: we went from supporting a handful of AWS accounts to owning infrastructure across several product lines and (together with other infra teams) being in charge of multiple cloud providers, supporting hundreds of engineers distributed across countries.
With the reorganisation came changes we didn't choose. One of them was moving from Jira to Linear (which honestly, I welcome). Another was inheriting collaboration processes that don't really scale.
In this new multi-cloud setup, cloud-ops engineers were reluctant to have product team engineers create tickets directly in Linear. They feared cluttering the backlog or addressing the wrong team (AWS? GCP? Azure?). So the default became a simple Slack message posted in a shared channel. Someone from the platform domain would read it, mentally triage it, and only then manually create a ticket in Linear for the right team.
The process had already been recently improved by adding a Slack Workflow that structured requests via a form; still a Slack message to be triaged, but at least with the relevant information nicely laid out.
I thought we could take it further: automate the hell out of it, and most importantly, reduce manual toil and noise.
AI-Assisted Flow from Request to Implementation
My goal was a streamlined pipeline:
- Slack stays the front door: engineers don't need to touch Linear or know which team/workspace to target
- Automation converts the request into a structured ticket in the right team (with AI filling in some additional context)
- AI-assisted triage ensures the ticket is complete, properly labeled, and actionable
- Spec-driven development turns well-described tickets into requirements and tasks that anyone can pick up
The tools: Slack Workflows, Linear Slack Integration, Linear MCP server, and Kiro with 2 custom Skills: Ticket Triage and Platform Support.
Step 1: Slack as the Front Door
Initially, to reduce friction for the teams (often cultural/organisational changes are the hardest and most time-consuming to perform), we decided to keep the same MultiCloud channel.
We didn't want to disrupt a process from one day to the other, so we added a couple of conventions that would simplify funnelling the requests (Slack Workflows are very simple and allow a great deal of customisation: type of trigger, chaining of several actions like opening a form, manipulating the entered data, forwarding it to a channel, or triggering something else).
- We edited the existing workflow to add the specification of the Cloud Provider if known (or inferable by e.g. the repo name; well, if the repo is called aws-terraform-modules, guess what provider that might be).
- We added another workflow to automatically ping the right team after the request (or during any Slack conversation) by simply using right cloud provider emojis
This made the initial manual triage quicker, and people got the hang of targeting the right team directly. Then, since for most topics - a team requesting access to a database, permissions to access an S3 bucket, or opening a PR to modify Terraform code - the requester would know whether the involved cloud provider/platform team is AWS or GCP, we gradually moved to a dedicated channel, leaving the shared one only for the transition (or for requests where ownership is still unclear: Cloudflare, Datadog infrastructure-as-code repositories, for example).
Triggering the workflow
In our case we chose to keep an explicit button in the channel,
but the workflow would also work with a simple shortcut: just type /aws in the channel's message composer and a form appears:
The form asks for the essentials: what they need, why, and how urgent it is. Once submitted, the content is posted to the channel for visibility and then routed to Linear through the Linear Slack AI integration.
Why not Linear's default Slack integration?
Linear's standard Slack integration (/linear) works fine for engineers who already know which team, project, and labels to pick. But for stakeholders submitting requests across a multi-cloud platform org, it wasn't enough. Most importantly, the form fields were too rigid (lacking our cycle, labels, and concerns customisation), thus resulting in poorly described tickets.
By routing through a Slack Workflow and letting AI parse the form content, we get richer tickets. The AI adds context, infers structure, and fills the ticket in the most relevant areas (relevant to us for estimation and prioritisation).
Step 2: AI-Assisted Triage: Making Tickets Actionable
This is where things get more interesting, especially in terms of AI-native SDLC and leveraging AI tools.
What is triage, anyway?
The term comes from emergency medicine: a nurse briefly assesses each patient's condition, determines risk and urgency, and routes them to the right place, all without performing the actual treatment.

Software triage works the same way. You're not solving the problem yet; you're making sure the problem is well-understood, correctly prioritised, and sitting in the right queue for someone to pick up.
In our case, once a ticket lands in the Triage inbox, it needs to be reviewed: is it actionable? Is the priority realistic? Is it really a critical blocker as it sounds, or can it simply be planned for the next cycle? (Often messages are overly dramatic, and often the priority set/inferred and the due date don't align.) Are the labels correct? Does the description contain enough information for someone to start working on it?
The Ticket-Triage Skill
I built this first as a Kiro Agent, then converted it to an Agent Skill so colleagues who don't use Kiro can also benefit.
Actually, as much as I enjoy creating and using custom sub-agents, in many circumstances I've started to find skills more handy (better context management than steering files, more context than simple prompts, and they don't require swapping agents for a recurring limited task; the only thing missing is automatic configuration of MCP servers and allowed tools).
The Skill connects to Linear via the Linear MCP server, pulls the ticket, and performs a structured assessment:
- Issue classification: determines the correct type (story, bug, support-request, technical-improvement, spike, security) based on content signals rather than what the reporter guessed
- Priority assessment: evaluates against a consistent scale (Urgent = production down; High = blocking work; Normal = standard feature; Low = nice-to-have)
- Discordance detection: catches mismatches between tone and priority, description and urgency, or priority and due date. A panicky "URGENT!!!" message with a deadline three weeks out gets flagged, as does a calm description hiding a genuine production blocker
- Completeness evaluation: checks for a clear problem statement, acceptance criteria, correct labels, appropriate estimate, dependencies, and most importantly: the "why" (business value or user need)
- Concern mapping: identifies which infrastructure area is involved (networking, compute, storage, CI/CD, observability, security, IaC) and applies the right labels
- Refinement guidance: if the ticket isn't ready, it generates specific questions to bounce back to the reporter while memory is still fresh
Under the hood: how the skill is structured
A Kiro Skill is essentially a structured markdown file (SKILL.md) with frontmatter metadata and a body that acts as a detailed prompt: it's a set of instructions, decision trees, and reference data that the AI agent follows when the skill is activated.
Here's what the Triage Skill contains:
1. Frontmatter: name, description, and trigger keywords that tell Kiro when to activate the skill:
---
name: triage-ticket
description: Triage and refine Linear issues through structured analysis.
Evaluates issue quality, detects discordance between tone and priority,
and enhances metadata.
---
2. Prerequisites: which MCP servers the skill depends on. In our case, the Linear MCP server is required (for fetching and updating tickets), and the GitHub MCP server is optional (for repo discovery during implementation suggestions):
{
"mcpServers": {
"linear": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.linear.app/mcp"]
}
}
}
3. A step-by-step workflow: the skill defines a structured triage process (fetch → classify → assess priority → detect discordance → evaluate completeness → produce report → research context → enhance). Each step has explicit instructions, decision tables, and output formats. For example, the discordance detection step includes a table of signal patterns:
**Tone vs Priority**: Look for urgent language ("ASAP", "critical",
"immediately", "blocking") paired with Normal/Low priority, or
casual/exploratory language with Urgent/High priority.
**Priority vs Due Date**: Urgent/High priority with distant or
missing due date. Low priority with immediate deadline.
4. Reference tables: concern mapping keywords, priority scales, due date guidelines, estimate ranges, and label definitions. These give the AI consistent criteria rather than relying on its general knowledge:
| Concern | Keywords |
|---|---|
| Networking | VPC, DNS, load balancer, ingress, service mesh |
| Compute | EKS, containers, pods, nodes, scaling |
| Storage | S3, EBS, databases, persistence, backups |
| CI/CD | Pipelines, GitHub Actions, deployments, ArgoCD |
| Security | IAM, policies, secrets, certificates, compliance |
5. Safety rules: explicit constraints like "never overwrite the original description," "always ask before modifying," and "implementation suggestions go in a comment, not inline." These prevent the AI from being overly aggressive with changes.
6. Skill composition: the triage skill explicitly calls the platform-support skill during step 7. This is declared as a dependency in the skill body:
## Dependency: platform-support skill
This skill activates the `platform-support` skill during triage
(Step 7) to understand the implementation context within our
ecosystem.
This composition pattern is powerful: each skill stays focused on its domain, but they can chain together for richer output. The triage skill handles the what and why; the platform-support skill handles the where and how.
The Platform-Support Skill the Triage-skill is depending on is essentially a living map of our infrastructure
It originated as a way to onboard the different members of various infra teams merged during the recent reorg and ease navigation across the current complexity. But our goal is, after we've extensively tested it, to release it to the feature teams as well, so they can rely on it as a first line of support (ask their AI agent using our skill rather than dropping a generic request in our Slack channel).
The Platform Support skill knows which repositories own what, which Terraform modules exist, which AWS accounts and environments are involved, what our CI/CD patterns look like, and what platform conventions (tagging, naming, security defaults) apply.
During triage, this means:
- Suggested implementations reference real repositories, modules, and workflows, not generic advice
- Affected AWS accounts and environments are correctly identified
- If a platform module already exists for what's being requested, the skill surfaces it (avoiding duplicate work or raw resource creation)
- Escalation paths point to the right channels
For example, if someone requests "I need a new S3 bucket for service X," the triage doesn't just label it and move on. It identifies which account the service lives in, checks if our terraform-module-library has an S3 module (where we've, for example, embedded security and compliance controls and set sensible defaults), notes the required tags and encryption defaults, and produces an implementation suggestion that an engineer can actually follow.
What the output looks like
After triage, the ticket gets enriched with two clearly separated sections:
Enhanced description: structured by issue type (user story format, bug report format, etc.), with acceptance criteria. The original description is always preserved verbatim below a separator, clearly marked as
(Original Request). We never overwrite what the reporter wrote.Implementation plan: added as a comment, clearly prefixed with
(AI Generated Suggested Implementation). This includes relevant repositories, affected accounts/environments, applicable platform modules, concrete steps, and conventions to follow.
We deliberately mark everything AI-generated as such. Until we gain more confidence in the output quality and the team builds trust in the process, transparency matters. Engineers know exactly what came from the reporter and what came from the AI, and they can override or discard the AI suggestions without losing context.
Let's be clear, this is nothing mindblowing. And at some point, we might even consider whether all this effort in AI automation is worth the credits/tokens. But for me, the multiplying effect is real. It's not that you can't do this manually, you absolutely can, but doing it with an AI assistant, in context, without switching windows, compounds over dozens of tickets per week. Less friction means triage happens promptly rather than piling up. And consistency improves: every ticket gets the same level of scrutiny regardless of who triages it or how busy the week is.
Step 3: From Triage to Implementation, and Toward Spec-Driven Development
This is where the pipeline pays off.
Once a ticket is well-described, with clear context, proper labels, realistic priority, identified concerns, a solid "why," and an AI-generated implementation plan grounded in our actual ecosystem, it's ready to be picked up.
What we do today
Right now, the triage output already includes a suggested implementation plan as a comment on the ticket. This isn't a full spec; it's a rough guide: which repos to touch, which modules to use, which accounts are affected, what conventions to follow. It gives the engineer picking the ticket from the Todo column a head start rather than a blank slate.
From there, the engineer pulls the ticket into their IDE via the Linear MCP server. For straightforward work, the implementation plan is enough to start coding. For complex work, they can ask Kiro to start a proper spec-driven development session, generating structured requirements, design decisions, and granular tasks, each step building on the previous. The spec can then be pushed back to the Linear ticket as a document, so everyone has visibility.
We don't yet push specs automatically; that's a next step. And honestly, I'm not fully convinced that specs will become the single source of truth that we version and diff rather than the AI-generated code itself. So for now, specs live on the feature branch (they don't land on main) and the ticket gets the implementation plan as a comment. Good enough for now; we'll iterate.
The quality of the spec depends entirely on the quality of the ticket. If triage is sloppy, specs will be vague. By investing in AI-assisted triage upstream, and grounding it in our actual infrastructure context via the Platform-Support Skill, we make everything downstream dramatically more useful.
The Full Pipeline
| Stage | Before (manual) | Now (AI-assisted) |
|---|---|---|
| Request intake | Slack message → someone reads it → manual ticket creation | Slack shortcut → structured form → auto-generated Linear ticket |
| Routing | Engineer guesses which team | Form + AI routes to the correct team |
| Triage | Open browser, read ticket, update fields one by one | Pull into IDE, AI reviews completeness, labels, priority, discordance |
| Clarification | Back-and-forth in Slack threads | Structured feedback with specific questions |
| Planning | Manual spec writing in docs or not at all | AI-generated specs from enriched ticket context |
| Implementation | Context-switch between tools | IDE-native with MCP server access to Linear |
None of these steps require AI. An engineer can do all of it manually. But the compound effect of removing small frictions, the tab switch, the copy-paste, the "let me re-read that Slack thread," the inconsistent triage, adds up to hours per week across a team now handling requests from hundreds of engineers.
In the past, even with a smaller team, a narrower scope, and team members who had worked together for months or years, we relied on time-consuming Agile rituals: backlog refinement, estimation poker, sprint planning. We often literally wasted time recalling what a specific ticket was about, because the description was poor or the ticket was just a placeholder (basically a title) for something we knew we should remember to work on, a bug fix or an improvement. Good triage eliminates that entire class of waste.
What I Learned
Start with the intake. If tickets are thin and poorly structured from the start, everything downstream suffers.
Keep it incremental. We didn't redesign everything at once. Slack workflow first, then Linear MCP integration, then triage skill, then specs. Each step delivered value on its own and built the foundation for the next.
Detect discordance early. One of the most valuable things the triage skill does is flag when tone and priority don't match. A frantic message with a relaxed deadline (or a calm request hiding a production blocker) gets caught before it distorts planning. Similarly, it highlights immediately if a ticket needs more refinement, so we can, while memory is still fresh, reach out to the reporter to bounce back the request or ask for clarification.
AI works best as a multiplier, not a replacement. The engineer still triages, still makes judgment calls, still writes the code. AI handles the mechanical parts: parsing, structuring, detecting discordance, fetching context, so the engineer can focus on decisions.
What's Next
- Evolving the Platform Support and Triage Skills into more comprehensive assistants
- Automatic spec generation triggered by ticket assignment
- Exploring whether triaging and implementation themself can be AI-assisted
I'd love in the coming weeks or months to push automation further. The recent release of Kiro Headless Mode allows running it within CI/CD pipelines, so I'd love to hook Linear to a pipeline that does a first level of triage automatically, bouncing back tickets that lack information, forwarding others to my team for clarification, and enriching tickets without human intervention.
The dream scenario
As our internal users create a request in Slack, a Linear ticket is generated, a Kiro agent picks it up, triages it and creates the specs, then another one follows the spec and implements the changes, directly opening a PR, and moving the ticket to "In Review."
Since we also have a custom AI-powered PR review skill, the review itself could be partially automated too, with the human in the loop only as final approval before pushing the deployment.
| Stage | Who | What happens |
|---|---|---|
| Request | Engineer (human) | Posts a request via Slack Workflow |
| Ticket creation | AI (Linear Slack integration) | Structured ticket generated in the right team |
| Triage & enrichment | AI (Kiro agent, headless) | Labels, priority, discordance check, implementation plan |
| Spec generation | AI (Kiro agent) | Requirements, design, tasks from enriched ticket |
| Implementation | AI (Kiro agent) | Follows the spec, writes code, opens a PR |
| Code review | AI (PR review skill) | Automated review for security, conventions, correctness |
| Approval & deploy | Engineer (human) | Final review, merge, deployment |
Request to PR, with AI doing the grunt work at every step. The human stays where it matters most: the final call.
But I'm deliberately not rushing there. My team is new to this scope, still navigating the complexity of multiple repos and accounts inherited from the reorg.
And most importantly, AI adoption is different across team members: I have someone very hyped ( and sometimes overrelying on it) and I have some sceptics.
The approach I'm taking is tiny steps that show how the boring, repetitive work gets automated while leaving as much of the actual coding fun as possible.
Nobody wants to feel replaced; everyone wants to feel unblocked.
If I can demonstrate that AI handles the toil (triage, boilerplate, ticket enrichment, PR descriptions) while engineers keep the interesting decisions and creative problem-solving, adoption will follow naturally.
We're early in this journey, but the direction is clear: less context-switching, more flow, and AI as a partner at every stage, from the moment an engineer posts a Slack message to the moment code ships.
Want to try this yourself?
I can't share the exact skills as they are today; they reference too much internal content (repository indexes, account mappings, Notion page IDs, team-specific conventions). But I'm planning to release a generic, customisable version on my GitHub that you can fork and adapt to your own organisation's setup. The structure and workflow logic will be the same; you'd just fill in your own repos, accounts, labels, and conventions.
Stay tuned, I'll link it here once it's ready.





























