The Case for Splitting AI Directives: A Three-Tiered Git Subtree Approach to Agentic Coding

If you’re running AI coding agents like Junie, Claude, or similar tools across multiple repositories, you’ve probably hit the same wall we did: how do you keep agent instructions consistent across projects without either duplicating everything or losing the ability to customize per-project? Here’s how we solved it using layered git subtrees, and why the structure has paid off.

The Problem: One Size Doesn’t Fit All

AI coding agents work best when given clear, explicit directives — how to commit code, which tools to prefer, how to structure new modules, what standards to follow. But an organization rarely has one set of rules that applies everywhere:

  • Some directives are genuinely universal and worth open-sourcing (e.g., “sign your commits”, “prefer IDE-native tooling over raw shell commands”).
  • Some directives encode proprietary business logic or internal architecture decisions that should never leave the company’s private infrastructure.
  • Some directives only make sense for one specific repository — its build profile, its issue tracker, its deployment quirks.

Cramming all of this into a single flat AGENTS.md file either leaks IP into open-source repository, or forces every project to carry irrelevant boilerplate, or both.

The Structure: Three Tiers, One Entry Point

Our solution is a lightweight AGENTS.md at the root of each repository that acts purely as a navigation index — it doesn’t contain directives itself, just pointers, read in priority order:

  1. Public AI Configurationdocs/public-ai-skills/Readme.md
  2. Private AI Configurationdocs/private-ai-skills/Readme.md
  3. Project AI Configurationdocs/project-ai-skills/Readme.md
  4. Followed by the standard README.md, and finally CHANGELOG.md for historical context only.
# Agent Navigation and Best Practices

This document provides directives to assist AI agents in navigating and working within the `blah` project.

1. Public AI Configuration: [docs/public-ai-skills/Readme.md](docs/public-ai-skills/Readme.md)
2. Private AI Configuration: [docs/private-ai-skills/Readme.md](docs/private-ai-skills/Readme.md)
3. Project AI Configuration: [docs/project-ai-skills/Readme.md](docs/project-ai-skills/Readme.md)
4. Project Readme: [README.md](README.md)
5. Changelog: only read this if looking for historical changes: [CHANGELOG.md](CHANGELOG.md)

Each tier lives in its own folder, and two of those folders — the public and private ones — are actually git subtrees, meaning they’re synced from independent, standalone repositories rather than being native content of the project.

Tier 1 — Public AI Skills (open source, shared broadly)

This layer holds directives that are safe and genuinely useful outside the company: preferring IDE tooling for file operations, commit-signing conventions, guidance on maintaining changelogs, and general Maven/archetype standards. Because it’s pulled from and pushed to a public GitHub repository (LimeMojito/ai-skills) via git subtree pull/push, any project that adopts this subtree automatically benefits when the shared skill set improves — and improvements we make while working in one codebase can flow back out to benefit every other project using the same subtree.

See out public AI skills in Github here.

Tier 2 — Private AI Skills (closed source, org-wide)

This layer holds directives that are proprietary — internal archetype preferences, closed-source skill documentation, and anything that shouldn’t be visible outside the organization. It’s synced from a private GitHub repository (LimeMojito/private-ai-skills) using the identical subtree mechanism. Crucially, it declares itself as taking precedence over the public tier: if a private directive contradicts a public one, private wins. This lets the organization override or refine open-source defaults without forking or duplicating the public skill files.

Tier 3 — Project AI Skills (local, repository-specific)

This layer is native to the project source itself — not a subtree. It captures things that only make sense in this one codebase: which Maven profile to build with, where the parent POM comes from, git/issue-number conventions specific to this repository’s GitHub project board, and pointers to deeper architectural docs. It sits on top of the other two tiers, adding concrete specifics without needing to touch the shared subtrees at all.

Why Split It Up At All?

1. Correct information hygiene. Proprietary business rules never accidentally end up in a public repository, because they physically live in a different, private repository. Conversely, generally useful conventions aren’t held hostage inside a closed-source project where other teams (or the open-source community) can’t benefit from them.

2. Reuse without duplication. Because the public and private tiers are git subtrees rather than copy-pasted files, an improvement made while working in any project using that subtree can be pushed upstream and pulled into every other project that shares it. Fix a directive once, and every repository benefits after the next subtree pull — no manual copy-paste, no drift between slightly different versions of “how to sign a commit.”

3. Clear precedence resolves conflicts predictably. With three tiers and an explicit priority order (private overrides public, project adds specifics on top of both), an agent never has to guess which rule wins when two directives disagree. The AGENTS.md index and the “Primary Directive” callout in the private tier make the resolution order unambiguous.

4. Right-sized context per project. A small open-source utility repo doesn’t need to carry a company’s entire internal tooling philosophy, and a proprietary project doesn’t need to expose its build secrets in a structure meant for public reuse. Each project only pulls in the tiers relevant to it, and the project-specific tier stays lean because it only needs to state what’s different from the shared layers.

5. Independent evolution and versioning. Because each tier is its own git history (two of them literally separate repositories), they can evolve at different speeds. Public conventions might change slowly and deliberately (since external consumers depend on them); private conventions can iterate quickly to match internal process changes; and project-specific tweaks can be made instantly without any subtree ceremony at all.

Conclusion

Treating AI agent directives as a layered, subtree-based configuration — rather than a single monolithic instructions file — mirrors a pattern we already trust in software architecture: separate concerns, share what’s common, override what’s specific, and keep proprietary information behind the right boundary. As more teams lean on coding agents day-to-day, this kind of structured directive management stops being a nice-to-have and starts being essential infrastructure, exactly like a shared library or a common CI pipeline.