6/6 · Portability becomes a Scale concern
Portable instructions require neutral sources, generated runtime outputs, release controls, and behavioral tests. Native primitives alone do not provide portability.
Written by Florian Bruniaux
AI Founding Engineer at Méthode Aristote, 13 years scaling engineering teams from developer to CTO. Builds open-source developer tools, see what else I've shipped.
| The Scale question | Can several people change tools without forking the team’s operating rules or losing verification? |
| The trap | Plain files and native primitives remain runtime-specific unless a controlled translation layer exists |
| The architecture | Neutral sources generate explicit outputs for each supported runtime |
| The routing layer | cc-bridge changes a model backend, but routing does not prove behavioral parity |
| The proof | Release manifests, generated-output checks, and behavioral tests bound the portability claim |
Five parts in, this series has built an instruction system: sources isolated from outputs, modules shared across developer profiles, behavioral audit in CI, and a sync pipeline as the operational backbone. Portability becomes a Scale concern when that system serves several developers, repositories, or runtimes. A migration can otherwise fork the team’s rules, tests, and evidence into incompatible copies.
The primary architecture reference is Portable agent configuration is a release system, not a shared folder. It defines the source model, generated artifacts, release manifest, installation boundaries, and evidence needed to claim support. This conclusion focuses on why those controls matter. Native primitives and a model router are useful components, but neither guarantees portability on its own.
Why this belongs to Scale
At Start, one person can keep a small instruction file close to one runtime. At Build, repeated tasks expose which rules, procedures, and checks deserve a stable home. Scale adds the coordination problem: several contributors need the same intent to survive different hosts, versions, repositories, and review paths.
The risk is not vendor choice by itself. It is uncontrolled divergence. A copied CLAUDE.md and AGENTS.md can look aligned on the day they are created, then drift independently. A common Markdown syntax can still carry different semantics across hosts. A successful model swap can still fail the team’s behavioral checks. Portability therefore needs an explicit support matrix and a release process, not a claim based on similar filenames.
The framework temptation
Google’s Agent Development Kit, CrewAI, LangChain: the appeal of agent frameworks is real. They abstract the orchestration layer, provide pre-built patterns for tool calling and memory, and get an agent running faster. For a prototype evaluated over a weekend, that’s a reasonable choice.
For a production system that six developers depend on, the framework tends to become a constraint. The abstractions that simplified the prototype now sit between you and the model’s native behavior. Debugging requires understanding the framework’s internal state before you can understand what the model actually did. Migrating to a new provider means adapting the framework bindings first. Adding a tool the framework doesn’t natively support means fighting the abstraction layer. The framework becomes the runtime, and the runtime becomes the lock-in.
Maxime Thoonsen argued that taking agent development seriously means investing in fundamentals rather than framework syntax, and that software architecture skills gain value as tools multiply (ep 307). Shell hooks, markdown modules, and YAML profiles all use a durable pattern: data-driven configuration with event-driven side effects. The specific tool that reads them can be swapped while the pattern stays.
Building directly on shell hooks, Markdown files, and YAML profiles can reduce framework dependencies and keep the system inspectable. Those properties help a migration, but they do not make host semantics equivalent. Each output still needs a named runtime, a generated artifact, an installation path, and a verification boundary.
Native primitives are inputs, not proof of portability
At Méthode Aristote, the Claude Code setup runs 25 shell hooks across the event lifecycle. The most visible is a global PostToolUse hook at ~/.claude/hooks/anti-ai-markers.sh. It fires after any Edit or Write call on .md, .mdx, or .txt files, strips code blocks and frontmatter before analysis, and checks for a defined set of detectable AI writing patterns: em dashes (U+2014), a curated list of overused adjectives in English and French that correlate with generated text, and mechanical transition phrases capped at one per text. A violation returns a decision: block signal and routes feedback to a style guide file. Because this is PostToolUse, the write has already happened: the signal prompts correction rather than undoing the edit. A preventive control belongs before execution. See the hook decision contract. No framework layer involved. The hook is a shell script, inspectable in two minutes, debuggable with bash -x.
The 56 procedural skills with disable-model-invocation: true follow the same logic. They cover committing, shipping a PR, creating a release, running production database operations, and scaffolding a new module. The user invokes them through an explicit slash command. The reason is documented for the Sentry-related skills: it prevents unsolicited automatic triage or fixes. The same principle applies across the procedural set. Side effects that matter stay under human control, and no framework decides when to trigger them.
BM25/lexical skill routing handles dispatch. A hook scores the incoming prompt against the skill library and routes to the best match. The target follow-rate is around 50%, measured weekly. That’s a calibration target, not a confirmed outcome yet, and the system gets sharper with each correction cycle. This replaces a framework’s intent classification with an inspectable scoring function over text, with results you can log and audit.
This makes the Claude Code behavioral layer inspectable without framework-specific knowledge. It says nothing by itself about whether Codex, Cursor, or another host will load the same files, expose the same events, or enforce the same decision. Portability begins when the neutral intent is translated into a host-specific artifact and verified on that host.
Model agnosticism: cc-bridge and neutral sources
The second half of portability concerns the model itself.
cc-bridge routes Claude Code requests according to the selected provider configuration. The public repository describes Copilot bridging, Anthropic Direct and Ollama as distinct routes. Provider support and protocol translation depend on the version in use. The diagram below isolates this routing relationship from the separate claim that a backend satisfies the same behavioral expectations.
The underlying principle goes back to how agent systems should be composed. Samy Lastmann described model swaps as a microservice replacement: each model in a pipeline should be swappable without breaking the pipeline, and performance metrics should be defined before the swap rather than measured after (ep 311). cc-bridge makes that operational at the routing layer. The swap is a config change, and the behavioral canary checks from part five tell you whether the new model passes the same expectations.
This differs from the API gateway layer described in part three. That layer, LiteLLM, Bifrost, and similar tools, intercepts API calls for cost compression and is structurally blind to Max and Pro subscriptions where no API key exists. cc-bridge routes for flexibility: testing a new model against the exact same instruction set the production model sees, falling back to a local model when a provider API is unavailable, or running a cheaper model on lower-stakes tasks without changing the configuration system that governs all of them.

The deeper portability starts in the source format. The modules in doc/guides/ai-instructions/modules/ are plain markdown. They contain no Claude-specific syntax, no Cursor-specific directives, and no framework-specific annotations. The profiles are YAML. The skeletons reference modules via {{module:name}} placeholders, a template convention the sync script resolves. This reduces source-level coupling, but a host can still lack an equivalent event, permission, or enforcement mechanism.
The outputs are where runtime specificity lives. pnpm ai:sync produces CLAUDE.md for Claude Code, .cursorrules for Cursor, AGENTS.md for Codex and OpenAI agents, .codex/config.toml for Codex terminal, and .mcp.json for MCP server configuration.
The portable agent configuration architecture documents the stricter release, installation, routing, and evidence boundaries behind this pattern. Its proven host scope is deliberately narrower than its target matrix: Claude Code and Codex have concrete adapters, while similar file formats do not count as runtime parity.
Each supported runtime needs an output adapter, a documented installation path, an entry in the support matrix, static validation of the generated artifact, and a behavior test on the host. A new adapter can reuse source modules where the host represents the same semantics. If it cannot, the source model or its declared support boundary also has to change.
The practical test asks what would need rewriting if the model layer changed tomorrow. With this architecture, the routing configuration, runtime adapter, installation mapping, and host-specific checks define the work. The twenty modules that encode project conventions, six profiles that capture developer preferences, and forty rule files remain reusable only for the semantics the destination host can represent and verify.

What survives a controlled migration
This series started with a measurement gap: same model, opposite outcomes, and the variable turned out to be how the context was built. It ends with a structural choice about how to build that context so it outlasts any single tool in the chain.
The durable decisions in the system described across these six parts live in neutral Markdown modules, explicit profiles, behavioral expectations, and a sync pipeline. Shell hooks and runtime files are adapters around those sources. Some adapters will need rewriting during a migration. The project knowledge and tests can survive if the release system keeps source, generated output, installation, and verification separate.
Quentin Adam offered a governance principle that applies at the tooling level: for AI infrastructure, avoid annual subscriptions and leave developers to choose their own tools, because the field changes too fast for any commitment that outlasts a short billing cycle (ep 341). The instruction system described here applies the same logic at the configuration level. Neutral sources and generated outputs reduce duplicated work. A tool change still requires a runtime adapter, installation mapping, support declaration, and behavioral checks before the team can claim compatibility.
Each article is self-contained, though reading the six parts in order is the shortest path to the full picture.
| Part | Focus |
|---|---|
| 1/6 · The science | Why context degrades and the +67% / -19% paradox |
| 2/6 · The discipline | Drift diagnosis, L0 to L5 control gaps, and the adherence-maintenance loop |
| 3/6 · The tooling | Four-layer token map, RTK, the MCP tax, the Max/Pro blind spot |
| 4/6 · The roles | Context engineer, harness engineer, spec engineer, agent identity architect, AI eval engineer |
| 5/6 · The team | Profiles, modules, sync pipeline, behavioral audit in CI |
| 6/6 · The portability | Neutral sources, runtime adapters, release evidence, and bounded support |
From the field, via IFTTD episode transcripts: Maxime Thoonsen, ep 307 on fundamentals over framework syntax; Samy Lastmann, ep 311 on model swaps as microservice replacements; Quentin Adam, ep 341 on avoiding lock-in at the tooling governance level.
If you’ve migrated an AI-instrumented codebase from one model provider to another, I’d be curious what the hardest part was. My instinct is that the model was the easy part. Questions, a different take, or something you’ve measured that contradicts any of this? I read everything on LinkedIn.
YSNK
(You should now know)
- The site’s own anti-AI-markers hook fires on every Edit or Write to
.md/.mdx/.txt, checks for em dashes, overused adjectives and mechanical transitions, and returns a block signal on a violation. A shell script handles that work and is inspectable in two minutes - 56 procedural skills run with
disable-model-invocation: true. An explicit slash command, rather than the model, triggers a release, a production database operation, or a Sentry fix - Lexical skill routing via BM25 targets roughly a 50% follow-rate, and that’s stated as a calibration target being measured weekly, not a confirmed outcome
- Swapping the model backend through cc-bridge changes routing configuration; behavioral checks still have to establish whether the new model meets the same expectations
- Portability is bounded by named adapters, release evidence, and host-specific verification, not by the fact that two runtimes accept Markdown files
Go Further in the Claude Code Guide
Practical resources selected to help you take the next step.
Open-source galaxy
Projects used in this path
Related articles
Portable agent configuration is a release system, not a shared folder
A release model for instructions, skills, Output Styles, hooks, MCP definitions and BM25 routing without confusing installed files with working behavior.
4/6 · The responsibilities around context engineering
A map of context engineering responsibilities: architecture, specifications, agent identity and evaluation, with practical directions for existing skills.
2/2 · Claude selected my output style. Then ignored it
Claude Code selected flow-lean but skipped its footer. A casing fix showed why installation, selection, and behavior need separate evidence.
Go deeper
Step-by-step guides that put this into practice.
Claude Code setup, level by level
Three configuration layers for project context, daily tools and persistent memory, with checks for what loads and how it behaves.
Claude Code security: the attack surface nobody audits
Hooks are shell scripts with your user permissions. MCP servers are third-party code with access to your credentials. Their timing and access depend on the configured events and server.
Context engineering: the L0-to-L5 playbook
Choose context controls from L0 to L5 according to the failure you observe, from project documentation to scoped rules, behavior checks and shared configuration.