<?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: David Emilio Sierra Puentes</title>
    <description>The latest articles on DEV Community by David Emilio Sierra Puentes (@juandelossantos).</description>
    <link>https://dev.to/juandelossantos</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%2F272079%2F59fc47e1-b3e9-4d92-910b-65ab1fdc2c36.jpeg</url>
      <title>DEV Community: David Emilio Sierra Puentes</title>
      <link>https://dev.to/juandelossantos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/juandelossantos"/>
    <language>en</language>
    <item>
      <title>How to add mechanical enforcement to any AI coding agent</title>
      <dc:creator>David Emilio Sierra Puentes</dc:creator>
      <pubDate>Mon, 13 Jul 2026 20:30:36 +0000</pubDate>
      <link>https://dev.to/juandelossantos/how-to-add-mechanical-enforcement-to-any-ai-coding-agent-2dbl</link>
      <guid>https://dev.to/juandelossantos/how-to-add-mechanical-enforcement-to-any-ai-coding-agent-2dbl</guid>
      <description>&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;AI coding agents generate code at impressive speeds. But they also commit untested code, hallucinate APIs, and forget your instructions the moment context fills up. If you've ever reviewed an AI-generated PR and thought "this looks right but I don't trust it," you've experienced the gap this framework fills.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/juandelossantos/another-agent-skills" rel="noopener noreferrer"&gt;github.com/juandelossantos/another-agent-skills&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prompts (CLAUDE.md, .cursorrules) work until they don't. The agent remembers until context degrades. Then it forgets. Mechanical enforcement via git hooks doesn't have that problem, hooks run regardless of what the agent remembers.&lt;/p&gt;

&lt;h3&gt;
  
  
  What you'll build
&lt;/h3&gt;

&lt;p&gt;By the end of this tutorial, you'll have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;14 pre-commit gates running on every commit&lt;/li&gt;
&lt;li&gt;A TDD gate that blocks code without tests&lt;/li&gt;
&lt;li&gt;57 composable skills your agent loads on demand&lt;/li&gt;
&lt;li&gt;A 6-phase development lifecycle (Define → Plan → Build → Verify → Review → Ship)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Install (10 seconds)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/juandelossantos/another-agent-skills.git
&lt;span class="nb"&gt;cd &lt;/span&gt;another-agent-skills
bash install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. The installer copies the framework to &lt;code&gt;~/.config/opencode/&lt;/code&gt; and sets up the skill loader.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Initialize in any project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;your-project
init-agents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;STACK_CONFIG.md&lt;/code&gt; — auto-detected test/lint/build commands&lt;/li&gt;
&lt;li&gt;Git hooks in &lt;code&gt;.git/hooks/&lt;/code&gt; (pre-commit v11, commit-msg v4)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.gitignore&lt;/code&gt; and &lt;code&gt;.env.example&lt;/code&gt; if missing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: How the gates work
&lt;/h3&gt;

&lt;p&gt;The pre-commit hook runs 14 checks before every commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Example: a commit is blocked&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"add feature"&lt;/span&gt;
⛔ BRANCH CHECK: on main — create a feature branch
⛔ STAGED CHECK: nothing staged — use git add
⛔ REMOTE SYNC: 3 unpulled commits — run git pull
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each gate must pass before the commit proceeds. The agent cannot use &lt;code&gt;--no-verify&lt;/code&gt; unless you explicitly allow it (and that override is tracked).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Example: a commit passes all gates&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"feat: add user auth"&lt;/span&gt;
✅ BRANCH CHECK: on feat/user-auth
✅ STAGED CHECK: 4 files staged
✅ REMOTE SYNC: up to &lt;span class="nb"&gt;date&lt;/span&gt;
✅ HTML INTEGRITY: all markers present
✅ SKILL GATE: skills were consulted
✅ ANTI-SLOP: no generic patterns detected
✅ TDD GATE: &lt;span class="nb"&gt;test &lt;/span&gt;files match code files
✅ TEST RUNNER: 29/29 tests passing
✅ All 14 gates passed → commit allowed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: The 6-phase lifecycle
&lt;/h3&gt;

&lt;p&gt;Every project follows the same disciplined flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEFINE → PLAN → BUILD → VERIFY → REVIEW → SHIP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each phase has corresponding skills:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DEFINE:&lt;/strong&gt; spec-driven-development, architecture-analysis, interview-me&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PLAN:&lt;/strong&gt; planning-and-task-breakdown&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BUILD:&lt;/strong&gt; incremental-implementation, test-driven-development, doubt-driven-development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VERIFY:&lt;/strong&gt; test-driven-development, debugging-and-error-recovery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REVIEW:&lt;/strong&gt; code-review-and-quality, security-and-hardening, performance-optimization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SHIP:&lt;/strong&gt; git-workflow-and-versioning, ci-cd-and-automation, shipping-and-launch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent loads skills on demand. 57 total, each with a declared Output Contract (artifact, format, location, quality criteria).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Customizing for your stack
&lt;/h3&gt;

&lt;p&gt;The framework auto-detects your stack from lockfiles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;init-agents
🔍 Detected: Node.js &lt;span class="o"&gt;(&lt;/span&gt;package.json&lt;span class="o"&gt;)&lt;/span&gt;
📝 Created: STACK_CONFIG.md with npm &lt;span class="nb"&gt;test&lt;/span&gt;, npm run lint, npm run build
🔗 Installed: 57 skills ready &lt;span class="k"&gt;for &lt;/span&gt;agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supports Node, Python, Rust, Go, Ruby, Dart, any stack with git.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this matters
&lt;/h3&gt;

&lt;p&gt;Most "AI agent frameworks" are prompt collections. They teach the agent. They don't enforce.&lt;/p&gt;

&lt;p&gt;This is a &lt;strong&gt;harness&lt;/strong&gt;. Mechanical infrastructure around the model. The difference between "please follow the rules" and "you literally cannot commit without passing 14 gates."&lt;/p&gt;

&lt;p&gt;57 skills. 14 gates. 6 harness components. 0 lint errors. MIT. Free.&lt;/p&gt;

&lt;p&gt;If you're building with AI agents and want production-grade guardrails:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/juandelossantos/another-agent-skills" rel="noopener noreferrer"&gt;github.com/juandelossantos/another-agent-skills&lt;/a&gt;, clone, run &lt;code&gt;bash install.sh&lt;/code&gt;, and star the repo ⭐&lt;/p&gt;

&lt;p&gt;10 seconds to your first gate.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>devops</category>
      <category>agentskills</category>
    </item>
    <item>
      <title>How I built mechanical enforcement for AI coding agents — and why prompts aren't enough</title>
      <dc:creator>David Emilio Sierra Puentes</dc:creator>
      <pubDate>Thu, 25 Jun 2026 17:30:44 +0000</pubDate>
      <link>https://dev.to/juandelossantos/how-i-built-mechanical-enforcement-for-ai-coding-agents-and-why-prompts-arent-enough-13bg</link>
      <guid>https://dev.to/juandelossantos/how-i-built-mechanical-enforcement-for-ai-coding-agents-and-why-prompts-arent-enough-13bg</guid>
      <description>&lt;p&gt;I spent months watching AI coding agents produce impressive demos that couldn't survive production.&lt;/p&gt;

&lt;p&gt;The code &lt;em&gt;looked&lt;/em&gt; right. It compiled. It even passed the first test.&lt;/p&gt;

&lt;p&gt;Then it hit edge cases. Forgotten constraints. A rule the agent agreed to five minutes ago, now gone — overwritten by the next context window.&lt;/p&gt;

&lt;p&gt;The root cause wasn't capability. It was &lt;strong&gt;process&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"A raw model is not an agent. It becomes one once a harness gives it state, tool execution, feedback loops, and enforceable constraints."&lt;/em&gt;&lt;br&gt;
— Osmani, Saboo &amp;amp; Kartakis, &lt;em&gt;The New SDLC With Vibe Coding&lt;/em&gt;, 2026 [1]&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The problem: capable but undisciplined
&lt;/h2&gt;

&lt;p&gt;AI agents are brilliant at generating code. They have zero built-in discipline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They commit without tests&lt;/li&gt;
&lt;li&gt;They push without review&lt;/li&gt;
&lt;li&gt;They overwrite each other's work&lt;/li&gt;
&lt;li&gt;They produce output that looks correct but breaks silently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;a href="https://arxiv.org/abs/2507.09089" rel="noopener noreferrer"&gt;METR study&lt;/a&gt; (Becker et al., July 2025 [2]) found something counterintuitive: developers using AI took &lt;strong&gt;19% longer&lt;/strong&gt; while &lt;em&gt;feeling&lt;/em&gt; 20% faster. The speed was an illusion. The debugging cost was real.&lt;/p&gt;

&lt;p&gt;The industry's response has been more skills, more prompts, bigger context windows. But the problem isn't intelligence — it's &lt;strong&gt;accountability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A rule that lives only in a prompt is a suggestion. An agent that "knows" the rules will eventually forget them. Context degrades. Attention drifts. The question isn't &lt;em&gt;if&lt;/em&gt; your agent will break a rule — it's &lt;em&gt;when&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The insight: memory is not enforcement
&lt;/h2&gt;

&lt;p&gt;Three incidents in 48 hours taught me this lesson.&lt;/p&gt;

&lt;p&gt;My agent bypassed its own commit approval system in under 30 seconds. Not because it was malicious — because the "gate" was just another rule in a file. Another thing to remember. Another thing to forget.&lt;/p&gt;

&lt;p&gt;I had built a SHA256 token system for commit approval. Thought it was bulletproof. Then my agent ran with &lt;code&gt;--auto&lt;/code&gt; and the tokens became theater.&lt;/p&gt;

&lt;p&gt;The fix wasn't a better token system. The fix was changing the architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rules that depend on memory fail. Rules that depend on visible blocks succeed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the core insight behind &lt;strong&gt;mechanical enforcement&lt;/strong&gt;: gates that run at the infrastructure level, not the agent level. The agent cannot bypass what it cannot ignore.&lt;/p&gt;




&lt;h2&gt;
  
  
  The solution: Agent = Model + Harness
&lt;/h2&gt;

&lt;p&gt;I built this project as a complete open-source implementation of the &lt;strong&gt;Harness architecture&lt;/strong&gt; [3] — the mechanical infrastructure that turns raw AI intelligence into reliable output.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;What It Is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Instructions &amp;amp; Rules&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Who the agent is, what it cares about, what it must never do&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tools&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;57 composable skills loaded on demand (lazy-loaded, ~250 lines each)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sandboxes &amp;amp; Execution&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Terminal, git workspace, CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Orchestration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;When each tool fires, how agents coordinate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Guardrails &amp;amp; Hooks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Deterministic enforcement at lifecycle points — pre-commit, commit-msg, approval&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Observability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Metrics, health checks, drift detection&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What makes this different:&lt;/strong&gt; Most "agent frameworks" are just prompt libraries. This one adds 12 mechanical pre-commit gates, a three-gate commit approval system, and a context engineering layer that saves ~45% of always-loaded tokens.&lt;/p&gt;




&lt;h2&gt;
  
  
  The code: a commit-msg hook that can't be bypassed
&lt;/h2&gt;

&lt;p&gt;Here's the heart of mechanical enforcement — a &lt;a href="https://github.com/juandelossantos/another-agent-skills/blob/main/scripts/git-hooks/commit-msg" rel="noopener noreferrer"&gt;&lt;code&gt;commit-msg&lt;/code&gt; git hook (v6)&lt;/a&gt; [4] that blocks unstamped commits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="c"&gt;# commit-msg — Three-Gate Approval Check (v6)&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

&lt;span class="nv"&gt;REPO_ROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--show-toplevel&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;APPROVAL_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_ROOT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.git/COMMIT_APPROVED"&lt;/span&gt;
&lt;span class="nv"&gt;MANIFEST_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_ROOT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.git/COMMIT_MANIFEST"&lt;/span&gt;
&lt;span class="nv"&gt;TEST_LOG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_ROOT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.git/TEST_LOG"&lt;/span&gt;
&lt;span class="nv"&gt;CURRENT_MSG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COMMIT_MSG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;NOW_EPOCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Gate 1: Tests passed recently?&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TEST_LOG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;STATUS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"^status="&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TEST_LOG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-f2-&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STATUS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"PASS"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;TS_EPOCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"^timestamp="&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TEST_LOG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-f2-&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;AGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;NOW_EPOCH &lt;span class="o"&gt;-&lt;/span&gt; TS_EPOCH&lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$AGE&lt;/span&gt; &lt;span class="nt"&gt;-le&lt;/span&gt; 3600 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;GATE1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
  &lt;/span&gt;&lt;span class="k"&gt;fi
fi&lt;/span&gt;

&lt;span class="c"&gt;# Gate 2: Commit manifest exists and has content?&lt;/span&gt;
&lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MANIFEST_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MANIFEST_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 20 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;GATE2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;

&lt;span class="c"&gt;# Gate 3: Approval fresh (&amp;lt;5 min) and message matches?&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$APPROVAL_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"^timestamp="&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$APPROVAL_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-f2-&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;STORED_MSG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"^message="&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$APPROVAL_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-f2-&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;TS_EPOCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; +%s 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;0&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;AGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;NOW_EPOCH &lt;span class="o"&gt;-&lt;/span&gt; TS_EPOCH&lt;span class="k"&gt;))&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$AGE&lt;/span&gt; &lt;span class="nt"&gt;-le&lt;/span&gt; 300 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STORED_MSG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CURRENT_MSG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;GATE3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
&lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# All three must pass&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GATE1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GATE2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GATE3&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✓ All 3 gates passed. Commit allowed."&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✗ Commit blocked — missing gates:"&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GATE1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  - Tests not run or expired"&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GATE2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  - Commit manifest missing"&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GATE3&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  - Approval missing or expired"&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Three conditions&lt;/strong&gt; must be met before any commit goes through:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tests passed&lt;/strong&gt; (within the last hour) — no blind commits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit manifest exists&lt;/strong&gt; (the agent writes what changed) — no silent mutations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User approved&lt;/strong&gt; (within 5 minutes, message matches) — no stale approvals&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The agent writes the approval file &lt;em&gt;after&lt;/em&gt; the user says "yes commit" in chat. The hook verifies the file is fresh (&amp;lt;5 min) and matches the exact commit message. If the agent tries to commit without approval, the hook blocks it — every time.&lt;/p&gt;

&lt;p&gt;This isn't a rule the agent &lt;em&gt;remembers&lt;/em&gt;. It's a gate the agent &lt;em&gt;cannot bypass&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The results: 57 skills, 12 gates, zero shortcuts
&lt;/h2&gt;

&lt;p&gt;After months of iteration, the project ships [5]:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Composable skills&lt;/td&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lazy-loaded guides&lt;/td&gt;
&lt;td&gt;54&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pre-commit gates&lt;/td&gt;
&lt;td&gt;9 (v8) + 3 commit-msg gates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enforcement levels&lt;/td&gt;
&lt;td&gt;4 (process → manifest → time-window → manifest gate)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent compatibility&lt;/td&gt;
&lt;td&gt;OpenCode, Claude Code, Cursor, Kiro, any git agent [6]
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context tokens saved&lt;/td&gt;
&lt;td&gt;~45% vs eager loading [7]
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stack support&lt;/td&gt;
&lt;td&gt;Node, Python, Rust, Go, Ruby, any language with git&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Price&lt;/td&gt;
&lt;td&gt;Free (MIT)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prompts are instructions. Gates are guarantees.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're building with AI agents, ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does your agent run tests before every commit? &lt;em&gt;Mechanically&lt;/em&gt;, not as a suggestion?&lt;/li&gt;
&lt;li&gt;Does your agent present changes for review before pushing? &lt;em&gt;Every time&lt;/em&gt;, not just when it remembers?&lt;/li&gt;
&lt;li&gt;Can your agent bypass its own rules? &lt;em&gt;If yes, those aren't rules — they're suggestions.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The gap between an "impressive demo" and "production-grade" isn't intelligence. It's the harness around it.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/juandelossantos/another-agent-skills.git
&lt;span class="nb"&gt;cd &lt;/span&gt;another-agent-skills
bash install.sh
init-agents   &lt;span class="c"&gt;# Activates skill-driven mode in any project&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;MIT. Free. Zero subscriptions. 57 skills. 12 gates.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://juandelossantos.github.io/another-agent-skills" rel="noopener noreferrer"&gt;juandelossantos.github.io/another-agent-skills&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What patterns have you found for keeping AI agents disciplined in production? I'd love to hear what's working (or not working) in your stack.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a id="ref1"&gt;&lt;/a&gt; Osmani, A., Saboo, S., &amp;amp; Kartakis, S. (2026). &lt;em&gt;The New SDLC With Vibe Coding: From ad-hoc prompting to Agentic Engineering.&lt;/em&gt; — &lt;a href="https://drive.google.com/file/d/1wNEl8FMpTso8aXlb_joxgzparxi-0ciM/view" rel="noopener noreferrer"&gt;Harness architecture paper&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a id="ref2"&gt;&lt;/a&gt; Becker, S. et al. (2025). &lt;em&gt;When Developers Use AI: Productivity and Perception.&lt;/em&gt; METR (Model Evaluation and Threat Research). — &lt;a href="https://arxiv.org/abs/2507.09089" rel="noopener noreferrer"&gt;arxiv.org/abs/2507.09089&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a id="ref3"&gt;&lt;/a&gt; Another Agent Skills. &lt;em&gt;Harness Architecture — The Six Components.&lt;/em&gt; — &lt;a href="https://github.com/juandelossantos/another-agent-skills/blob/main/docs/HARNESS.md" rel="noopener noreferrer"&gt;&lt;code&gt;docs/HARNESS.md&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a id="ref4"&gt;&lt;/a&gt; Another Agent Skills. &lt;em&gt;commit-msg hook (v6) — Three-Gate Approval Check.&lt;/em&gt; — &lt;a href="https://github.com/juandelossantos/another-agent-skills/blob/main/scripts/git-hooks/commit-msg" rel="noopener noreferrer"&gt;&lt;code&gt;scripts/git-hooks/commit-msg&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a id="ref5"&gt;&lt;/a&gt; Another Agent Skills. &lt;em&gt;Repository and Documentation.&lt;/em&gt; — &lt;a href="https://github.com/juandelossantos/another-agent-skills" rel="noopener noreferrer"&gt;github.com/juandelossantos/another-agent-skills&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a id="ref6"&gt;&lt;/a&gt; Another Agent Skills. &lt;em&gt;Agent Adapters — Compatibility Matrix.&lt;/em&gt; — &lt;a href="https://github.com/juandelossantos/another-agent-skills/blob/main/docs/AGENT-ADAPTERS.md" rel="noopener noreferrer"&gt;&lt;code&gt;docs/AGENT-ADAPTERS.md&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a id="ref7"&gt;&lt;/a&gt; Another Agent Skills. &lt;em&gt;Context Budget — Lazy Loading Architecture.&lt;/em&gt; — &lt;a href="https://github.com/juandelossantos/another-agent-skills?tab=readme-ov-file#context-budget" rel="noopener noreferrer"&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a id="ref8"&gt;&lt;/a&gt; Singhal et al. (2026). &lt;em&gt;Agent Skills: Evaluation-Driven Development for AI Coding Agents.&lt;/em&gt; Google Research. — &lt;a href="https://drive.google.com/file/d/1Wso-CM4aAvTxFZa5wjBntKM3IVSg7PWW/view" rel="noopener noreferrer"&gt;Paper&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a id="ref9"&gt;&lt;/a&gt; Osmani, A. (2026). &lt;em&gt;The Factory Model: From Conductors to Orchestrators.&lt;/em&gt; — &lt;a href="https://addyosmani.com/blog/future-agentic-coding/" rel="noopener noreferrer"&gt;addyosmani.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a id="ref10"&gt;&lt;/a&gt; Another Agent Skills. &lt;em&gt;SOUL.md — Project Identity and Principles.&lt;/em&gt; — &lt;a href="https://github.com/juandelossantos/another-agent-skills/blob/main/SOUL.md" rel="noopener noreferrer"&gt;&lt;code&gt;SOUL.md&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
