<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Tools on Mikhail Shogin</title><link>https://mshogin.com/categories/tools/</link><description>Recent content in Tools on Mikhail Shogin</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>Mikhail Shogin</copyright><lastBuildDate>Tue, 24 Mar 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://mshogin.com/categories/tools/index.xml" rel="self" type="application/rss+xml"/><item><title>AI Agent Linter Ecosystem: Quality, Cost and Safety Control</title><link>https://mshogin.com/blog/ai-linter-ecosystem/</link><pubDate>Tue, 24 Mar 2026 00:00:00 +0000</pubDate><guid>https://mshogin.com/blog/ai-linter-ecosystem/</guid><description>&lt;h2 id="the-problem"&gt;The Problem
&lt;/h2&gt;&lt;p&gt;AI agents write code fast, but speed comes at a cost. Literally - tokens cost money. And figuratively - code quality degrades without oversight.&lt;/p&gt;
&lt;p&gt;I hit three problems at once:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Architecture degrades&lt;/strong&gt; - agents write working code that violates layer boundaries, creates circular dependencies and god classes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Costs grow&lt;/strong&gt; - complex prompts go to Opus at $15/1M tokens when Haiku at $0.80 would suffice&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Content isn&amp;rsquo;t filtered&lt;/strong&gt; - production prompts contain things that shouldn&amp;rsquo;t be there&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each problem has its own tool. But when the tools work together, they amplify each other.&lt;/p&gt;
&lt;h2 id="the-pipeline"&gt;The Pipeline
&lt;/h2&gt;&lt;p&gt;Every request passes through a chain of linters, each responsible for its domain:&lt;/p&gt;
&lt;div class="mermaid"&gt;
graph LR
A[Prompt] --&gt; B[seclint]
B --&gt;|safe| C[promptlint]
B --&gt;|blocked| X[Reject]
C --&gt;|haiku| D1[Agent: Haiku]
C --&gt;|sonnet| D2[Agent: Sonnet]
C --&gt;|opus| D3[Agent: Opus]
D1 --&gt; E[archlint]
D2 --&gt; E
D3 --&gt; E
E --&gt;|pass| F[costlint]
E --&gt;|fail| C
F --&gt; G[Done]
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;seclint&lt;/strong&gt; - checks content safety (6+/12+/16+/18+ ratings)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;promptlint&lt;/strong&gt; - scores complexity, picks the model&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent&lt;/strong&gt; - executes the task on the selected model&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;archlint&lt;/strong&gt; - validates the result for architecture violations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;costlint&lt;/strong&gt; - records cost, tracks cache hit rate&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If archlint rejects the result, the task escalates to a more powerful model. costlint records the escalation cost.&lt;/p&gt;
&lt;h2 id="the-tools"&gt;The Tools
&lt;/h2&gt;&lt;h3 id="archlint---architecture-linter"&gt;archlint - Architecture Linter
&lt;/h3&gt;&lt;p&gt;Scans Go projects for structural violations.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;archlint scan --format json ./project/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;What it finds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Layer violations (handler calls repository directly)&lt;/li&gt;
&lt;li&gt;God classes (&amp;gt;20 methods or &amp;gt;15 dependencies)&lt;/li&gt;
&lt;li&gt;Circular dependencies&lt;/li&gt;
&lt;li&gt;Interface Segregation violations (interfaces &amp;gt;5 methods)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Metrics: fan-out, coupling (Ca/Ce), component and link counts.&lt;/p&gt;
&lt;p&gt;GitHub: &lt;a class="link" href="https://github.com/mshogin/archlint" target="_blank" rel="noopener"
&gt;mshogin/archlint&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="promptlint---complexity-based-router"&gt;promptlint - Complexity-Based Router
&lt;/h3&gt;&lt;p&gt;Scores prompt complexity and picks the model. No LLM, pure metrics, &amp;lt;10ms.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Fix typo in README&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; promptlint analyze --output-model
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# haiku&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Design microservices with CQRS&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; promptlint analyze --output-model
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# opus&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Signals: length, sentence count, domain keywords, action type (fix/create/refactor), code presence.&lt;/p&gt;
&lt;p&gt;Integrates with ccproxy for real Claude Code request routing through a proxy.&lt;/p&gt;
&lt;p&gt;GitHub: &lt;a class="link" href="https://github.com/mikeshogin/promptlint" target="_blank" rel="noopener"
&gt;mikeshogin/promptlint&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="costlint---token-cost-analysis"&gt;costlint - Token Cost Analysis
&lt;/h3&gt;&lt;p&gt;Tracks spending, analyzes caching, runs A/B tests between models.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;costlint report --source telemetry.jsonl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Cost Report:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Total requests: 342
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; By model:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; opus: 48 requests, ~$12.60
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sonnet: 195 requests, ~$6.50
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; haiku: 99 requests, ~$0.44
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; With optimal routing: ~$8.20 (savings: 58%)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Cache metrics: hit rate, block reuse, content entropy, Jaccard similarity.
A/B testing: 30/30/40 traffic split, per-group cost and quality metrics.&lt;/p&gt;
&lt;p&gt;GitHub: &lt;a class="link" href="https://github.com/mikeshogin/costlint" target="_blank" rel="noopener"
&gt;mikeshogin/costlint&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="seclint--promptsec---content-filter"&gt;seclint / promptsec - Content Filter
&lt;/h3&gt;&lt;p&gt;Age ratings for prompts: 6+, 12+, 16+, 18+.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Help with math homework&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; seclint rate
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# {&amp;#34;rating&amp;#34;: &amp;#34;6+&amp;#34;, &amp;#34;safe&amp;#34;: true}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Explain SQL injection for security course&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; seclint rate
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# {&amp;#34;rating&amp;#34;: &amp;#34;16+&amp;#34;, &amp;#34;safe&amp;#34;: true, &amp;#34;flags&amp;#34;: [&amp;#34;security_tools&amp;#34;]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Considers educational context - explaining SQL injection for a security course gets 16+ instead of 18+.&lt;/p&gt;
&lt;p&gt;GitHub: &lt;a class="link" href="https://github.com/mikeshogin/seclint" target="_blank" rel="noopener"
&gt;mikeshogin/seclint&lt;/a&gt; / &lt;a class="link" href="https://github.com/mikeshogin/promptsec" target="_blank" rel="noopener"
&gt;mikeshogin/promptsec&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="shared-principles"&gt;Shared Principles
&lt;/h2&gt;&lt;p&gt;All tools follow the same rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Go&lt;/strong&gt; - single stack, single build&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No LLM&lt;/strong&gt; - pure metrics, regex, keyword matching. &amp;lt;10ms per request&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CLI + HTTP&lt;/strong&gt; - each tool works as a command and as a server&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JSONL telemetry&lt;/strong&gt; - unified log format for analysis&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipeline-friendly&lt;/strong&gt; - exit codes, stdout, pipes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="numbers"&gt;Numbers
&lt;/h2&gt;&lt;p&gt;On test workload (342 requests over a week):&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Token spending&lt;/td&gt;
&lt;td&gt;$19.54&lt;/td&gt;
&lt;td&gt;$8.20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture violations&lt;/td&gt;
&lt;td&gt;63&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requests to expensive model&lt;/td&gt;
&lt;td&gt;100% opus&lt;/td&gt;
&lt;td&gt;14% opus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Routing latency&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;&amp;lt;10ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;58% cost savings without quality loss - simple tasks go to Haiku, architecture tasks stay on Opus.&lt;/p&gt;
&lt;h2 id="orchestration"&gt;Orchestration
&lt;/h2&gt;&lt;p&gt;The tools work autonomously, but deliver maximum impact together. For orchestration we use &lt;a class="link" href="https://github.com/kgatilin/myhome" target="_blank" rel="noopener"
&gt;myhome&lt;/a&gt; - daemon-based AI agent management with workflow stages and scheduled tasks.&lt;/p&gt;
&lt;p&gt;The stack:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;myhome launches agents&lt;/li&gt;
&lt;li&gt;promptlint picks the model (pre-route hook)&lt;/li&gt;
&lt;li&gt;archlint validates output (quality gate stage)&lt;/li&gt;
&lt;li&gt;costlint tracks cost (telemetry consumer)&lt;/li&gt;
&lt;li&gt;seclint filters incoming prompts (pre-filter)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="get-started"&gt;Get Started
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install all tools&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go install github.com/mshogin/archlint@latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go install github.com/mikeshogin/promptlint/cmd/promptlint@latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go install github.com/mikeshogin/costlint/cmd/costlint@latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go install github.com/mikeshogin/seclint/cmd/seclint@latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Start routing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;promptlint serve &lt;span class="m"&gt;8090&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;seclint serve &lt;span class="m"&gt;8091&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Check architecture&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;archlint scan --format json ./my-project/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# View costs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;costlint report --source ~/.promptlint/telemetry.jsonl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="links"&gt;Links
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/mshogin/archlint" target="_blank" rel="noopener"
&gt;archlint&lt;/a&gt; - architecture linter&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/mikeshogin/promptlint" target="_blank" rel="noopener"
&gt;promptlint&lt;/a&gt; - complexity router&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/mikeshogin/costlint" target="_blank" rel="noopener"
&gt;costlint&lt;/a&gt; - cost analysis&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/mikeshogin/seclint" target="_blank" rel="noopener"
&gt;seclint&lt;/a&gt; / &lt;a class="link" href="https://github.com/mikeshogin/promptsec" target="_blank" rel="noopener"
&gt;promptsec&lt;/a&gt; - content filter&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/kgatilin/myhome" target="_blank" rel="noopener"
&gt;myhome&lt;/a&gt; - agent orchestration&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/mshogin/archlint/blob/main/ECOSYSTEM.md" target="_blank" rel="noopener"
&gt;ECOSYSTEM.md&lt;/a&gt; - integration map&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>$HOME in Git: One Config for Claude Code</title><link>https://mshogin.com/notes/claude-config-consolidation/</link><pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate><guid>https://mshogin.com/notes/claude-config-consolidation/</guid><description>&lt;p&gt;Multiple projects. Each with its own CLAUDE.md, its own rules. You improve something in one place - you want it elsewhere. Copy. Improve there. Copy back. Round and round.&lt;/p&gt;
&lt;p&gt;At some point I had a mess of different versions of the same rules scattered across a dozen projects. The copy-paste circus was annoying, but I kept putting it off.&lt;/p&gt;
&lt;p&gt;During the New Year holidays, I decided to fix it.&lt;/p&gt;
&lt;h2 id="the-solution"&gt;The Solution
&lt;/h2&gt;&lt;p&gt;Moved everything to my home directory &lt;code&gt;~/.claude/&lt;/code&gt;. One config for all projects.&lt;/p&gt;
&lt;p&gt;Yes, I&amp;rsquo;m now coupled to my home directory structure. But that structure hasn&amp;rsquo;t changed in years - &lt;code&gt;~/my/&lt;/code&gt; for projects, &lt;code&gt;~/education/&lt;/code&gt; for learning, &lt;code&gt;~/family/&lt;/code&gt; for family stuff. Risk is minimal.&lt;/p&gt;
&lt;h2 id="structure"&gt;Structure
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;~/.&lt;/span&gt;&lt;span class="n"&gt;claude&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CLAUDE&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="c1"&gt;# Core principles (task confirmation, formatting)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;HOME_MAP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="c1"&gt;# Home directory map for navigation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="c1"&gt;# Rules (auto-loaded)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;architecture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="c1"&gt;# Architecture principles&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;coaching&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="c1"&gt;# Coaching questions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dna&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="c1"&gt;# Writing style&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;navigation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="c1"&gt;# Context detection by keywords&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;projects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="c1"&gt;# Project-specific rules&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;aitrader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="c1"&gt;# Rules for aitrader&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;commands&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="c1"&gt;# Slash commands&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="c1"&gt;# /ms-todos - task list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="c1"&gt;# /ms-add-note - add note&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;skills&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="c1"&gt;# Skills&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;blog&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;writing&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="c1"&gt;# Blog post writing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;review&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="c1"&gt;# Go code review&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;social&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="c1"&gt;# Social media content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="c1"&gt;# Custom agents&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;reviewer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="c1"&gt;# Go code reviewer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;hooks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="c1"&gt;# Hooks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="c1"&gt;# Session logging&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="how-navigation-works"&gt;How Navigation Works
&lt;/h2&gt;&lt;p&gt;The key file is &lt;code&gt;HOME_MAP.md&lt;/code&gt;. It&amp;rsquo;s a map of the entire home directory with context detection rules.&lt;/p&gt;
&lt;p&gt;Claude sees keywords in your request and knows which directory to work in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;aitrader&lt;/code&gt;, &lt;code&gt;archlint&lt;/code&gt;, &lt;code&gt;blog&lt;/code&gt; -&amp;gt; &lt;code&gt;~/my/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;course&lt;/code&gt;, &lt;code&gt;book&lt;/code&gt;, &lt;code&gt;learning&lt;/code&gt; -&amp;gt; &lt;code&gt;~/education/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;memory&lt;/code&gt;, &lt;code&gt;remember&lt;/code&gt;, &lt;code&gt;mission&lt;/code&gt; -&amp;gt; &lt;code&gt;~/my/org-roam/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If context is ambiguous - it asks.&lt;/p&gt;
&lt;h2 id="project-specific-rules"&gt;Project-Specific Rules
&lt;/h2&gt;&lt;p&gt;Need specific rules for a project? Add them to &lt;code&gt;rules/projects/&lt;/code&gt;. For example, &lt;code&gt;aitrader.md&lt;/code&gt; contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to run the collector (without proxy for Tinkoff API)&lt;/li&gt;
&lt;li&gt;Test commands&lt;/li&gt;
&lt;li&gt;Project specifics&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These rules load globally but apply only when working in the aitrader context.&lt;/p&gt;
&lt;h2 id="git"&gt;Git
&lt;/h2&gt;&lt;p&gt;Everything under git. One repository, one history.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.gitignore&lt;/code&gt; is large - it excludes almost everything that shouldn&amp;rsquo;t be versioned: credentials, caches, Downloads, Documents, Library, .ssh. But everything else - configs, &lt;code&gt;.claude/&lt;/code&gt;, dotfiles - is tracked. Planning to add private repos as submodules, so one &lt;code&gt;git clone&lt;/code&gt; restores the entire home directory.&lt;/p&gt;
&lt;p&gt;No more copying between projects. Improve a rule once - it works everywhere.&lt;/p&gt;
&lt;h2 id="result"&gt;Result
&lt;/h2&gt;&lt;p&gt;Before: a dozen projects with scattered CLAUDE.md files, constant copying, different versions of the same thing.&lt;/p&gt;
&lt;p&gt;After: one &lt;code&gt;~/.claude/&lt;/code&gt;, structured rules, git for versioning. Improve once - works everywhere.&lt;/p&gt;
&lt;p&gt;Downside: tight coupling to home directory structure. For me it&amp;rsquo;s not a problem - the structure is stable.&lt;/p&gt;</description></item></channel></rss>