DEV Community

Aman Suryavanshi
Aman Suryavanshi

Posted on Originally published at amansuryavanshi.me

The Multi-Agent Symlink Kernel: Orchestrating Autonomous Agents Without Context Drift

How to Orchestrate Claude Code, OpenCode, and Antigravity with a Symlink Kernel (Without Context Drift)

TL;DR:

  • Copy-pasting AI skills across Claude Code, OpenCode, and Antigravity causes immediate capability divergence and broken tool paths.
  • File-level hardlinks fail because modern editors use atomic writes (saving to temp files, deleting the target, and severing underlying NTFS inodes).
  • A 2-layer filesystem architecture using NTFS Directory Junctions (mklink /J) and SHA-256 drift guards synchronizes thirty custom skills across six agent harnesses with zero sync latency and zero memory overhead.

Prerequisites

Before implementing this architecture, make sure your environment meets these baselines:

  • Windows 10/11 with Developer Mode enabled (allows running mklink without improves administrator shells).
  • At least two installed AI coding CLI tools (for example, Claude Code, OpenCode, Antigravity, or Codex).
  • PowerShell 7+ installed for cryptographic drift-check automation.
  • Basic familiarity with terminal path variables and symlinks.

The problem: multi-agent capability drift

When running a single coding assistant, prompt maintenance is straightforward. The moment I expanded my local development workflow to six specialized agents, my toolchain fractured.

I use Antigravity for high-level architectural planning, Claude Code for terminal refactoring and execution, OpenCode for long-running repository loops, and Codex for second-opinion audits. Each tool lives in its own isolated filesystem world:

  • Claude Code looks inside ~/.claude/skills/
  • OpenCode reads from ~/.config/opencode/skills/
  • Antigravity queries ~/.gemini/antigravity/skills/
  • Codex parses ~/.codex/skills/

Over months of building production client infrastructure, I built thirty custom workflows. These include n8n-master for building webhook orchestrations, nextjs-expert for Next.js App Router rules, and owasp-security for defensive vulnerability auditing.

To make these workflows available everywhere, I initially copied and pasted skill folders into each agent directory. That naive decision introduced immediate capability drift.

I would encounter an edge case while working inside Claude Code, patch a scraping bug in a skill script, and finish the task. Two days later, I would trigger OpenCode for a background task, and it would fail on the exact bug I had already solved. The agents were running diverging versions of my workflows. I had zero visibility into which harness held the latest patch, and 30% to 40% of my debugging time went into resolving desynchronized instructions.


What I tried first (that failed)

Failure 1: The Windows atomic save trap with hard links

My first reflex was to replace copied directories with standard NTFS file-level hard links (mklink /H). In theory, every agent would point directly to the same underlying disk inode.

In practice, the links broke silently after a single file edit. Modern editors such as VS Code and Cursor do not overwrite files in place. They perform atomic saves: write the updated buffer to a temporary file, delete the target file from disk, and rename the temporary file to the original filename.

Because an NTFS hard link binds directly to the specific Master File Table (MFT) record, deleting the target file severs the link permanently. The editor created a brand-new inode for the edited file, leaving every other agent stranded on the dead, orphaned record.

Failure 2: openCode configuration parser crashes on relative paths

Next, I attempted to link a centralized instruction repository using relative file paths inside OpenCode's configuration file at ~/.config/opencode/opencode.json.

// ~/.config/opencode/opencode.json (Broken attempt)
{
 "instructions": ["../../.gemini/global-configs/opencode/global-standards.md"]
}
Enter fullscreen mode Exit fullscreen mode

OpenCode crashed instantly on startup. Its configuration parser resolves relative paths against its internal binary runtime path rather than the active workspace root. When I tried symlinking the entire opencode.json file to version control it, OpenCode corrupted the link during runtime whenever it toggled model providers. Symlinking dynamic configuration files created continuous process crashes.


The solution architecture: the private multi-agent symlink kernel

I discarded user-space file-watching daemons and moved the sync abstraction directly into the operating system filesystem. The Private Multi-Agent Symlink Kernel separates concerns into two isolated planes:

  1. The Canonical Skills Registry: A single directory holding all thirty tool-equipped workflows. I project this folder into each agent harness using NTFS Directory Junctions (mklink /J). Junctions operate at the directory namespace layer rather than the inode layer, making them completely immune to editor file-deletion and atomic rename cycles.
  2. The Private Configuration Kernel: A dedicated Git repository housing my sensitive operating invariants, master prompt rules, and thin entry pointers. This repository remains isolated from public skill directories to prevent accidentally pushing proprietary client standards to remote registries.
flowchart TD
 subgraph Local_Storage["Local Storage Layer"]
 CSR["Canonical Skills Registry<br/>(~/.gemini/antigravity/skills/)"]
 PCK["Private Config Kernel<br/>(~/.gemini/global-configs/)"]
 end

 subgraph Reparse_Points["NTFS Directory Junctions (mklink /J)"]
 J1["Claude Code (~/.claude/skills/)"]
 J2["OpenCode (~/.config/opencode/skills/)"]
 J3["Codex (~/.codex/skills/)"]
 J4["Antigravity (~/.antigravity/skills/)"]
 end

 subgraph Thin_Pointers["2-Layer Thin Pointers (<= 85 Lines)"]
 P1["CLAUDE.md"]
 P2["global-standards.md"]
 P3["AGENTS.md"]
 end

 CSR , >|0ms Reparse Point| J1
 CSR , >|0ms Reparse Point| J2
 CSR , >|0ms Reparse Point| J3
 CSR , >|0ms Reparse Point| J4

 PCK , >|SHA-256 Drift Guard| Thin_Pointers

The Multi-Agent Symlink Kernel: Orchestrating Autonomous Agents Without Context Drift


Implementation step-by-step

Step 1: Establish the canonical directory junctions

Run these commands in Windows Terminal with Developer Mode active. Replace <username> with your local system user name:

:: Create junction for Claude Code
mklink /J "C:/Users/<username>/.claude/skills" "C:/Users/<username>/.gemini/antigravity/skills"

:: Create junction for OpenCode
mklink /J "C:/Users/<username>/.config/opencode/skills" "C:/Users/<username>/.gemini/antigravity/skills"

:: Create junction for Codex
mklink /J "C:/Users/<username>/.codex/skills" "C:/Users/<username>/.gemini/antigravity/skills"

:: Create junction for DeepSeek Harness
mklink /J "C:/Users/<username>/.dsh/skills" "C:/Users/<username>/.gemini/antigravity/skills"
Enter fullscreen mode Exit fullscreen mode

Because these are native filesystem reparse points, the operating system kernel resolves reads in place. When Claude Code executes a skill, disk I/O routes directly to the physical clusters of the canonical registry with zero CPU polling loops and zero sync latency.

Step 2: Implement the 2-layer thin pointer standard

A common failure mode in multi-agent setups is dropping a 25KB master instruction file into CLAUDE.md or GEMINI.md. When an agent ingests 25KB of static markdown on every turn, it consumes 15% of its context window on instructions that get summarized away during prompt compaction.

To prevent this, I instituted The 2-Layer Thin Pointer Standard. Root entry files (CLAUDE.md, GEMINI.md, AGENTS.md) are hard-capped at 85 lines. They hold only non-negotiable behavioral invariants and instruct the model to read extended documentation on demand via explicit file reads.

Here is a production thin pointer from my local environment:

<., ~/.claude/CLAUDE.md , >
# Core Invariants for Claude Code

- Never execute destructive Git commands without confirmation.
- Code style: TypeScript strict mode, functional composition, no any types.
- Error handling: Always fail closed with explicit error structures.
- File editing: Verify file existence and checksum before modifying.

## Extended Architectural Standards
For domain-specific tasks, read the canonical standard file before modifying code:
- Next.js: ~/.gemini/global-configs/standards/nextjs-standards.md
- API Pipelines: ~/.gemini/global-configs/standards/pipeline-standards.md
- Security: ~/.gemini/global-configs/standards/owasp-standards.md
Enter fullscreen mode Exit fullscreen mode

Step 3: Deploy configuration drift guards with PowerShell

For agent configuration files that cannot be linked via directory junctions (such as root markdown prompts that need static local existence), I use an automated deployment script. It computes SHA-256 hashes for every target file, reports configuration drift, and deploys updates deterministically.

Save this script inside your private configuration repository:

# deploy-global-rules.ps1
# Deploys canonical rule files from git repo to live agent home paths.
param(
 [switch]$Check,
 [switch]$Force
)
$ErrorActionPreference = "Stop"
$repoRoot = $PSScriptRoot

$map = @(
 @{ Repo = "claude/CLAUDE.md"; Live = "$env:USERPROFILE/.claude/CLAUDE.md" },
 @{ Repo = "gemini/GEMINI.md"; Live = "$env:USERPROFILE/.gemini/GEMINI.md" },
 @{ Repo = "opencode/global-standards.md"; Live = "$env:USERPROFILE/.config/opencode/rules/global-standards.md" },
 @{ Repo = "codex/AGENTS.md"; Live = "$env:USERPROFILE/.codex/AGENTS.md" },
 @{ Repo = "dsh/AGENTS.md"; Live = "$env:USERPROFILE/.dsh/AGENTS.md" },
 @{ Repo = "qoder/AGENTS.md"; Live = "$env:USERPROFILE/.qoder/AGENTS.md" }
)

Write-Host "=== Deploy Global Rules (repo -> live) ===" -ForegroundColor Green
if ($Check) { Write-Host "MODE: CHECK (diff-only, no writes)" -ForegroundColor Yellow }

$drift = 0
foreach ($m in $map) {
 $src = Join-Path $repoRoot $m.Repo
 $dst = $m.Live
 if (.(Test-Path $src)) {
 Write-Host " [MISS] repo source not found: $src" -ForegroundColor Red
 continue
 }

 $srcHash = (Get-FileHash $src -Algorithm SHA256).Hash
 $dstHash = if (Test-Path $dst) { (Get-FileHash $dst -Algorithm SHA256).Hash } else { "MISSING" }

 if ($srcHash -eq $dstHash) {
 Write-Host " [OK] in sync: $dst" -ForegroundColor Gray
 continue
 }

 $drift++
 Write-Host " [DRIFT] differs: $dst" -ForegroundColor Yellow
 if ($Check) { continue }

 if (-not $Force) {
 $ans = Read-Host " Overwrite live with repo copy? (y/N)"
 if ($ans -ne "y") { Write-Host " skipped." -ForegroundColor Gray; continue }
 }

 $dstDir = Split-Path $dst
 if (.(Test-Path $dstDir)) { New-Item -ItemType Directory -Path $dstDir -Force | Out-Null }
 Copy-Item $src $dst -Force
 Write-Host " deployed." -ForegroundColor Green
}

if ($Check) {
 Write-Host "`nCheck complete. $drift file(s) drifted from repo source of truth." -ForegroundColor Cyan
} else {
 Write-Host "`nDeploy complete." -ForegroundColor Green
}
Enter fullscreen mode Exit fullscreen mode

The Multi-Agent Symlink Kernel: Orchestrating Autonomous Agents Without Context Drift

Click to view raw verification logs

PS C:/Users/dev/.gemini/global-configs&gt; powershell -File deploy-global-rules.ps1 -Check
=== Deploy Global Rules (repo -&gt; live) ===
MODE: CHECK (diff-only, no writes)
 [OK] in sync: C:/Users/dev/.claude/CLAUDE.md
 [OK] in sync: C:/Users/dev/.gemini/GEMINI.md
 [DRIFT] differs: C:/Users/dev/.config/opencode/rules/global-standards.md
 [OK] in sync: C:/Users/dev/.codex/AGENTS.md
 [OK] in sync: C:/Users/dev/.dsh/AGENTS.md
 [OK] in sync: C:/Users/dev/.qoder/AGENTS.md

Check complete. 1 file(s) drifted from repo source of truth.
Run without -Check to deploy, or run backup-global-rules.ps1 if LIVE is newer.
Enter fullscreen mode Exit fullscreen mode

Production trade-offs

Every architectural decision has costs. Here are the explicit trade-offs in this design:

  1. Directory Junctions vs. Dotfile Managers: Using NTFS directory junctions eliminates third-party dependencies and removes background sync daemons entirely. The trade-off is cross-platform portability. NTFS junctions require Windows-specific syntax (mklink /J). When deploying to macOS or Linux environments, you must swap these commands for native Unix symbolic links (ln -s).
  2. Thin Pointers vs. Context Availability: Keeping entry prompts under 85 lines reduces prompt token consumption and prevents context compaction amnesia. The trade-off is that the agent must make an additional filesystem tool call to read extended standards when solving complex domain problems, adding one execution step to initial task planning.

Real-world proof

This symlink kernel is not a demo. It is the operating foundation for all my production systems.

I run this exact architecture across thirty production skills while managing systems like my 74-node OmniPost-Core pipeline (maintaining 99.7% uptime reliability) and the client digital platform for Aviators Training Centre (which generated over ₹3,00,000 in revenue).

Centralizing custom skills into OS-level reparse points means that when I patch an edge case in Claude Code, my background workers in OpenCode and Antigravity inherit that solution instantly.


Key takeaways

  • Avoid copy-pasting skills across agent directories. Centralize them in one canonical folder and project them outward using directory-level junctions.
  • Do not use file hardlinks for editable code. Atomic editor writes will sever hardlinks by deleting and recreating the file on write.
  • Apply the 2-Layer Thin Pointer Standard. Keep root prompt files under 85 lines to prevent prompt compaction amnesia, and link extended rules on demand.
  • Isolate private agent governance from shared skill folders using a dedicated Git-backed configuration kernel.

I am documenting my entire multi-agent orchestration architecture on Dev.to. Follow along for the next architectural teardowns.


Community debate

I prefer native operating system filesystem primitives like NTFS Directory Junctions over dedicated dotfile managers like GNU Stow or Chezmoi because they operate with zero background process overhead.

Where do you draw the line between OS filesystem primitives and dedicated dotfile managers when orchestrating multi-agent developer environments? How do you prevent your rule files from competing with codebase tokens during long agent sessions?

Key Takeaways

  • Replace manual skill copying with centralized OS Directory Junctions (mklink /J) to achieve zero-latency updates across all agent harnesses.
  • Avoid file-level hardlinks (mklink /H) for editable rulebooks because modern IDE atomic saves sever inode bindings silently.
  • Enforce the 2-Layer Thin Pointer Standard by restricting root entry rulebooks to 85 lines or fewer to eliminate prompt token bloat.
  • Isolate sensitive organizational instructions and client rules within a private Git repository completely separated from public skill directories.
  • Deploy cryptographic SHA-256 drift verification to audit and synchronize rule changes deterministically across agent surfaces.

FAQ

Why does Claude Code ignore rules in CLAUDE.md during long sessions?

Claude Code deprioritizes instructions in CLAUDE.md during long sessions because active conversation tokens and codebase context push initial system prompts out of the model's effective attention window. When context compaction occurs, long rulebooks are summarized and compressed. To prevent instruction amnesia, cap your root CLAUDE.md file at 85 lines or fewer using thin pointers that instruct the model to load specific rule files on demand.

What is the difference between a Windows Directory Junction and a Symbolic Link?

A Windows Directory Junction (mklink /J) is an NTFS reparse point that resolves directory targets locally on the host machine without requiring elevated administrator privileges. Symbolic links (mklink /D) can target remote network shares and relative paths, but often require administrative permissions or Windows Developer Mode. For local multi-agent skill routing, directory junctions provide the most stable cross-directory binding.

How do I prevent sensitive client rules from leaking into public AI skill folders?

To protect sensitive data, separate your configuration into two distinct planes: store public, shareable skills in a canonical registry, and isolate proprietary operating instructions, client architecture rules, and credentials in a private, version-controlled Git repository. Use thin pointer entry files in your agent home directories that reference the private repository paths directly.

Top comments (0)