<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: kabirnarang39</title>
    <description>The latest articles on DEV Community by kabirnarang39 (@kabirnarang39).</description>
    <link>https://dev.to/kabirnarang39</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4053918%2Fbcaa1447-1425-427c-a0fa-a0cd8afe6823.jpg</url>
      <title>DEV Community: kabirnarang39</title>
      <link>https://dev.to/kabirnarang39</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kabirnarang39"/>
    <language>en</language>
    <item>
      <title>I let Claude Code build a real security tool, here's the honest writeup</title>
      <dc:creator>kabirnarang39</dc:creator>
      <pubDate>Sun, 09 Aug 2026 19:51:14 +0000</pubDate>
      <link>https://dev.to/kabirnarang39/i-let-claude-code-build-a-real-security-tool-heres-the-honest-writeup-4aa8</link>
      <guid>https://dev.to/kabirnarang39/i-let-claude-code-build-a-real-security-tool-heres-the-honest-writeup-4aa8</guid>
      <description>&lt;p&gt;AI agents now call tools, MCP servers, and each other on their own. That is the&lt;br&gt;
whole point of an agent. It is also the problem: the moment an agent is&lt;br&gt;
compromised — a prompt injection, a leaked key, a poisoned tool result — it&lt;br&gt;
keeps its credentials and its network path, and nothing between it and your&lt;br&gt;
systems says no.&lt;/p&gt;

&lt;p&gt;Most of the stack around agents watches and reports. It logs the calls, maybe&lt;br&gt;
scores them, and pages a human. By the time the human reads the page, the agent&lt;br&gt;
has made a thousand more calls.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;Wardline&lt;/strong&gt; to enforce instead of watch. It's a control-plane proxy: an&lt;br&gt;
AI agent reaches its MCP servers, tools, and gRPC upstreams &lt;em&gt;only&lt;/em&gt; through&lt;br&gt;
Wardline, which applies identity, policy, budget, and anomaly detection&lt;br&gt;
in-process and writes every decision to an audit trail. One static Go binary —&lt;br&gt;
no database, no identity provider, no sidecar to start.&lt;/p&gt;
&lt;h2&gt;
  
  
  The part that's actually different: auto-block
&lt;/h2&gt;

&lt;p&gt;Alerting is easy and everyone does it. The claim worth making is enforcement.&lt;/p&gt;

&lt;p&gt;Wardline keeps a per-identity behavioral baseline using &lt;strong&gt;Welford's algorithm&lt;/strong&gt; —&lt;br&gt;
a running mean and variance over four features per time window: call rate,&lt;br&gt;
distinct-tool count, deny ratio, and mean inter-arrival time. No training data,&lt;br&gt;
no external model, no history to store. Each completed window is scored as a&lt;br&gt;
combined z-score against that identity's own baseline.&lt;/p&gt;

&lt;p&gt;When the score crosses a configured threshold and &lt;code&gt;auto_block&lt;/code&gt; is on, Wardline&lt;br&gt;
doesn't just write an anomaly record — it &lt;strong&gt;rejects that identity's calls&lt;/strong&gt; for a&lt;br&gt;
bounded TTL. The compromised agent is cut off in real time, with no rule written&lt;br&gt;
for the specific attack and no human in the loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// The detector wires a real BlockChecker as the blocker; when the combined&lt;/span&gt;
&lt;span class="c"&gt;// z-score exceeds the auto-block threshold, the identity is blocked.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AutoBlock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enabled&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blocker&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;blockScore&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AutoBlock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ScoreThreshold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blocker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Identity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tenant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;/* reason */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The decision path benchmarks at ~33ns / 0 allocations on the default YAML&lt;br&gt;
backend.&lt;/p&gt;
&lt;h2&gt;
  
  
  The part most projects won't tell you: what it does &lt;em&gt;not&lt;/em&gt; catch
&lt;/h2&gt;

&lt;p&gt;The auto-block catches &lt;em&gt;abrupt&lt;/em&gt; deviation. It does &lt;strong&gt;not&lt;/strong&gt; catch &lt;em&gt;low-and-slow&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Because the baseline is self-learned and unsupervised, an attacker who ramps&lt;br&gt;
activity gradually — staying within a few standard deviations of the moving&lt;br&gt;
baseline each window — is never blocked. The baseline adapts upward and absorbs&lt;br&gt;
the ramp. Wardline blocks the agent that suddenly does 10x its normal rate; it&lt;br&gt;
does not block the agent that patiently climbs to 10x over an hour.&lt;/p&gt;

&lt;p&gt;This isn't a threshold you can simply tighten. Tighten it and you start blocking&lt;br&gt;
normal agents — the false-positive rate is regression-guarded to stay near zero&lt;br&gt;
on steady traffic, and that guard is the thing keeping the feature usable. It's&lt;br&gt;
an inherent tradeoff of unsupervised, per-identity baselining.&lt;/p&gt;

&lt;p&gt;Both behaviors are pinned by tests in the repo —&lt;br&gt;
&lt;code&gt;TestDetector_AutoBlock_AbruptSpikeIsBlocked&lt;/code&gt; and&lt;br&gt;
&lt;code&gt;TestDetector_AutoBlock_LowAndSlowEvades&lt;/code&gt; — so the boundary is documented, not&lt;br&gt;
marketed around.&lt;/p&gt;

&lt;p&gt;The takeaway isn't "anomaly detection is weak." It's that anomaly detection is&lt;br&gt;
the &lt;em&gt;last&lt;/em&gt; line, not the only one. Keep explicit policy and budget limits as the&lt;br&gt;
hard floor — they bound absolute behavior regardless of ramp speed — and let&lt;br&gt;
auto-block catch the fast, obvious compromise that policy didn't anticipate.&lt;/p&gt;
&lt;h2&gt;
  
  
  Secure by default is a claim; read the defaults
&lt;/h2&gt;

&lt;p&gt;Wardline fails closed on policy. It does &lt;strong&gt;not&lt;/strong&gt; fail closed on identity or the&lt;br&gt;
dashboard by default: identity is trusted from the &lt;code&gt;X-Wardline-Identity&lt;/code&gt; header&lt;br&gt;
(spoofable) and the dashboard's read views are unauthenticated, until you turn on&lt;br&gt;
the flags that change that. The binary logs a &lt;code&gt;WARN&lt;/code&gt; on startup for every&lt;br&gt;
insecure default still in effect, so the posture is never silent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;features&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;credential_issuance&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;   &lt;span class="c1"&gt;# verify a signed bearer token instead of trusting the header&lt;/span&gt;
  &lt;span class="na"&gt;rbac&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;                  &lt;span class="c1"&gt;# gate the dashboard and admin actions on real permissions&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  About the "built with Claude Code" part
&lt;/h2&gt;

&lt;p&gt;I'll be transparent, because the honesty is the whole theme: Claude Code did the&lt;br&gt;
bulk of the implementation, under my direction. Architecture, threat model, and&lt;br&gt;
every design decision are mine and were reviewed by me. The workflow was&lt;br&gt;
spec-driven — spec → plan → build → and on any failure, trace the root cause and&lt;br&gt;
update the spec before retrying. That loop is what kept ~46k lines of Go coherent&lt;br&gt;
instead of drifting into slop: ~950 tests, race + coverage in CI, golangci-lint&lt;br&gt;
clean, Clean Architecture actually enforced.&lt;/p&gt;

&lt;p&gt;The contribution I valued most wasn't code volume — it was that it kept pushing&lt;br&gt;
me to &lt;em&gt;document&lt;/em&gt; limitations (like the low-and-slow gap) and write tests proving&lt;br&gt;
them, rather than ship an impressive demo that overpromised. For a security tool,&lt;br&gt;
that's exactly the instinct you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it fits
&lt;/h2&gt;

&lt;p&gt;Wardline is young and unproven at scale — that's the honest status. It's not&lt;br&gt;
trying to replace an LLM router like LiteLLM or a managed gateway like Portkey.&lt;br&gt;
It's the enforcement-first control plane for the traffic &lt;em&gt;between&lt;/em&gt; an agent and&lt;br&gt;
everything it calls, in a single self-hosted binary, Apache-2.0.&lt;/p&gt;

&lt;p&gt;If that's the layer you're missing, the repo is here:&lt;br&gt;
&lt;strong&gt;&lt;a href="https://github.com/kabirnarang39/wardline" rel="noopener noreferrer"&gt;github.com/kabirnarang39/wardline&lt;/a&gt;&lt;/strong&gt;.&lt;br&gt;
Feedback on the anomaly approach and the threat model is exactly what I'm after —&lt;br&gt;
poke holes.&lt;/p&gt;

</description>
      <category>go</category>
      <category>security</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Your Claude Skill Passed Every Review</title>
      <dc:creator>kabirnarang39</dc:creator>
      <pubDate>Wed, 29 Jul 2026 21:23:59 +0000</pubDate>
      <link>https://dev.to/kabirnarang39/your-claude-skill-passed-every-review-1lnc</link>
      <guid>https://dev.to/kabirnarang39/your-claude-skill-passed-every-review-1lnc</guid>
      <description>&lt;p&gt;Here's a scenario that's already happened to someone reading this, they just don't know it yet.&lt;/p&gt;

&lt;p&gt;You write a Claude Skill. You test it by hand — a few prompts, looks good, ship it. It works for months. Then Anthropic ships a new model. Nothing about your skill changed. But the model reads your instructions slightly differently now: it stops triggering on a phrasing that used to work, or it triggers fine but quietly drops a constraint it used to follow, or it still does the right thing but now costs three times as much to get there.&lt;/p&gt;

&lt;p&gt;There's no error. No stack trace. No red CI badge. The skill just… drifts. You find out the way everyone finds out — a workflow breaks downstream, a review comes back wrong, a support ticket shows up, and twenty minutes into debugging you realize: it's not your code, it's the model, and it changed weeks ago.&lt;/p&gt;

&lt;p&gt;Every other kind of software would have caught this on day one&lt;br&gt;
If a dependency bump broke your app, you'd have a failing test in CI before it ever reached staging. If a database migration corrupted a query, your integration suite would go red immediately. That's not because those systems are magic — it's because someone decided, a long time ago, that "did this still work after the thing underneath it changed" deserves to be a test, not a vibe.&lt;/p&gt;

&lt;p&gt;Skills don't have that yet. Most SKILL.md files in the wild have never been tested against more than one model, because until recently there wasn't a standard way to test them at all. Anthropic clearly sees the gap too — skill-creator now ships with evals, benchmark mode, and A/B testing between skill versions, which is a real step forward for authoring a skill well. But authoring-time testing answers "does this work today." It doesn't answer "does this still work six months from now, on a model that didn't exist when I wrote it" — and that second question is the one that actually burns teams, because it fails silently, in production, on someone else's schedule.&lt;/p&gt;

&lt;p&gt;What a safety net for this actually looks like&lt;br&gt;
Not a one-time eval you ran once and forgot about. A safety net that:&lt;/p&gt;

&lt;p&gt;Re-runs automatically against every model in your matrix, not just the one you tested on originally&lt;br&gt;
Diffs against last-known-good, so a flaky one-off doesn't cry wolf and a real regression can't hide in the noise&lt;br&gt;
Turns a caught failure into permanent coverage — the exact gap that just bit you gets written down as a test case automatically, so it can never silently regress twice&lt;br&gt;
Tells you which commit broke it, the same way git bisect tells you which commit broke a normal test, instead of leaving you to guess&lt;br&gt;
Treats adversarial input as a real test category, not an afterthought — prompt injection, jailbreak attempts, and instruction leakage are things a skill can regress on too, and most testing setups don't check for that at all&lt;br&gt;
That's the actual shape of the problem. It's not "skills need more eval prompts." It's "skills need the same CI discipline every other piece of software has had for twenty years, and nobody had built it yet."&lt;/p&gt;

&lt;p&gt;So I built it&lt;br&gt;
SkillCI is an open-source CLI that treats a Claude Skill like any other piece of software with a regression suite:&lt;/p&gt;

&lt;p&gt;skillci check — a local, zero-API-call lint mapped to OWASP's Agentic Skills Top 10 (prompt injection risk, over-privileged access, unpinned dependencies) plus basic bloat checks. Free, no API key, catches the obvious stuff before you even run a model.&lt;br&gt;
skillci regress — runs your eval suite across every model in your config, diffs against the last known-good run, and fails CI only on a new regression, not on every pre-existing flaky case.&lt;br&gt;
The self-growing eval loop — when regress catches a failure with zero prior coverage, it doesn't just print red text. It writes the missing test case for you, so skillci accept turns "we got lucky this time" into permanent, tracked coverage. Catch once, covered forever.&lt;br&gt;
skillci bisect — real git worktree-based binary search over your skill's own commit history, so when something breaks, you get a culprit commit instead of a guessing game.&lt;br&gt;
Redteam plugins — prompt injection, jailbreak attempts (including multi-turn crescendo attacks), PII exfiltration, SSRF-bait, and more, run against your skill the same way a pentest would, with a successful attack becoming a permanent regression case exactly like a caught model drift does.&lt;br&gt;
It's complementary to skill-creator's evals, not a replacement — skill-creator helps you author a good skill today; skillci watches it stay correct over time, across models you haven't tested yet and commits you haven't shipped yet.&lt;/p&gt;

&lt;p&gt;Try it in under a minute, no API key needed&lt;br&gt;
brew install kabirnarang39/skillci/skillci&lt;br&gt;
skillci check path/to/your-skill&lt;br&gt;
That's the free, local-only half — no ANTHROPIC_API_KEY, no network calls, just a static scan that'll tell you if your skill is carrying obvious risk. The full regression loop needs a key, but you can see whether this is worth your time before spending a single API call.&lt;/p&gt;

&lt;p&gt;It's early — the core CLI is stable, the dashboard is newer, and I'd genuinely rather hear "here's what's missing" than silence. If you've been burned by a skill that quietly stopped working, or you're maintaining enough skills that this is starting to feel like a real problem instead of a hypothetical one, I'd like to know what broke and how you found out. That's the next thing I'm building toward.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/kabirnarang39" rel="noopener noreferrer"&gt;
        kabirnarang39
      &lt;/a&gt; / &lt;a href="https://github.com/kabirnarang39/skillci" rel="noopener noreferrer"&gt;
        skillci
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      CI for Claude Skills — lint, eval, and regression-test SKILL.md files across a model matrix, with a self-growing eval loop that turns uncovered regressions into permanent test cases.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;SkillCI&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Regression testing for Claude Skills.&lt;/strong&gt; When a model update silently changes how your skill behaves, SkillCI catches it in CI — and turns the failure into a permanent test case, automatically.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/kabirnarang39/skillci/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/kabirnarang39/skillci/actions/workflows/ci.yml/badge.svg" alt="CI"&gt;&lt;/a&gt;
&lt;a href="https://scorecard.dev/viewer/?uri=github.com/kabirnarang39/skillci" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b17637beaace03a72ccbee1982d8520120f66640c58ba1caceb9b0f4cfeb6f03/68747470733a2f2f6170692e73636f7265636172642e6465762f70726f6a656374732f6769746875622e636f6d2f6b616269726e6172616e6733392f736b696c6c63692f6261646765" alt="OpenSSF Scorecard"&gt;&lt;/a&gt;
&lt;a href="https://github.com/kabirnarang39/skillci/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a549a7a30bacba7bfceebdc207a8e86c3f2c02995a2527640dca30048fd2b64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d417061636865253230322e302d626c75652e737667" alt="License: Apache 2.0"&gt;&lt;/a&gt;
&lt;a href="https://github.com/kabirnarang39/skillci/go.mod" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6b4ff39b898a48e8b1c1c987f5e5c19e1b4ec96af210ecafa1179b2720162c60/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f676f2d312e32352532422d3030414444383f6c6f676f3d676f" alt="Go Version"&gt;&lt;/a&gt;
&lt;a href="https://pkg.go.dev/github.com/kabirnarang39/skillci" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1342daf716cbb098e30b82341a7fe969143488035b448ba26bd62995dda0953a/68747470733a2f2f706b672e676f2e6465762f62616467652f6769746875622e636f6d2f6b616269726e6172616e6733392f736b696c6c63692e737667" alt="Go Reference"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/kabirnarang39/skillci/.github/assets/demo.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fkabirnarang39%2Fskillci%2FHEAD%2F.github%2Fassets%2Fdemo.gif" alt="SkillCI demo: skillci check, regress across a model matrix, catching an uncovered failure, generating an eval case, and accepting it"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A skill fails against a model it's never been tested on → SkillCI doesn't just report red, it &lt;strong&gt;writes the missing test case for you&lt;/strong&gt; (&lt;code&gt;evals/_generated/...&lt;/code&gt;) so &lt;code&gt;skillci accept&lt;/code&gt; turns it into permanent coverage. That loop — catch once, covered forever — is the whole point.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/kabirnarang39/skillci#why" rel="noopener noreferrer"&gt;Why&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#whats-inside" rel="noopener noreferrer"&gt;What's inside&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#how-this-compares" rel="noopener noreferrer"&gt;How this compares&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#install" rel="noopener noreferrer"&gt;Install&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#quick-start" rel="noopener noreferrer"&gt;Quick start&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#github-actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#optional-hosted-dashboard" rel="noopener noreferrer"&gt;Dashboard&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#vs-code-extension" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#compliance-evidence-reports" rel="noopener noreferrer"&gt;Compliance reports&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#for-ai-agents-the-skillci-guardrails-skill" rel="noopener noreferrer"&gt;For AI agents&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#mcp-server" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#commands" rel="noopener noreferrer"&gt;Commands&lt;/a&gt; · &lt;a href="https://github.com/kabirnarang39/skillci#status" rel="noopener noreferrer"&gt;Status&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;You write a Claude Skill. It works today. Six months from now, Anthropic ships a new model, and nobody tested your skill against it first — because until now, no tool did that automatically…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/kabirnarang39/skillci" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;If this is a problem you've hit, a star helps others find it — and tells me what to build next.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
