{"slug": "aic-packages-need-an-interface-for-coding-agents", "title": "AIC: Packages Need an Interface for Coding Agents", "summary": "A developer introduced AIC (Agent Index Convention), a draft protocol for packages to expose an interface for coding agents. The convention separates provider packages, host repositories, and coding agents, addressing issues of ownership, freshness, discovery, and composition when multiple packages share agent-facing context.", "body_md": "I develop several tightly related repositories at the same time.\n\nSome are reusable SDKs for declarative schemas, infrastructure, stateful workflows, and other domain abstractions. Others are applications that consume several of those SDKs together.\n\nThe development loop constantly crosses package boundaries.\n\n```\n SDK A ──────┐\n             │\n SDK B ──────┼──▶ application\n             │        │\n SDK C ──────┘        │\n    ▲                 │\n    └──── feedback ───┘\n```\n\nI've already written about why I don't think this requires a monorepo, and why I prefer the repository itself to carry the current source of truth:\n\nI won't repeat those arguments here.\n\nThis post starts one layer later.\n\nAs these SDKs became more agent-aware, each package started needing to tell coding agents how it should be used.\n\nI was already using project-local surfaces such as `.claude/`\n\n, `.codex/`\n\n, `AGENTS.md`\n\n, and package-specific skills. They are useful. Explicit project-local context works.\n\nThe maintenance was the awkward part.\n\nWhen an SDK changed, I would tell the agent to update the corresponding instructions, rules, or skills in the consuming repository.\n\nThat worked too.\n\nBut after doing it repeatedly across several packages and repositories, I noticed something:\n\nMy repeated update instructions had quietly become an undocumented protocol.\n\nWhich files should change?\n\nWhich source is canonical?\n\nWhat should be copied?\n\nWhat should only be referenced?\n\nWhat belongs to the package, and what belongs to the consuming repository?\n\nHow should different coding-agent harnesses receive the same package knowledge without creating independent copies?\n\nI initially thought I needed a better synchronizer.\n\nI now think the problem is one layer higher.\n\nPackages already have an interface for programs. They increasingly need an interface for coding agents.\n\nI've been calling the protocol I'm using for that interface **AIC — Agent Index Convention**.\n\nIt is still a draft from my own development environment. The exact mechanics will change.\n\nThe boundary it describes feels much more stable.\n\nPackages already know how to introduce themselves to programs:\n\n```\npackage name\nversion\nAPI\ntypes\nschemas\nconfig\nCLI\n```\n\nA coding agent needs another set of facts:\n\n```\nwhere is the current manual?\nwhich rules matter?\nwhich skills are available?\nwhich files are generated?\nwhich commands are safe?\nwhich host-specific configuration applies?\n```\n\nI think of this as the package's **agent-facing interface**.\n\nThe problem appears when several packages expose that interface inside the same host repository.\n\nWithout a shared convention, each package tends to solve the problem independently.\n\n```\npackage A ──▶ AGENTS.md\npackage B ──▶ CLAUDE.md\npackage C ──▶ .claude/skills/\npackage D ──▶ .codex/...\n```\n\nEach integration can be perfectly reasonable in isolation.\n\nComposition introduces a different set of problems.\n\n| Concern | Failure mode |\n|---|---|\n| Ownership | one package overwrites human or provider-owned context |\n| Freshness | copied instructions drift from the installed package |\n| Discovery | harnesses load different files and directories |\n| Composition | every package assumes it owns the shared surface |\n\nThis stopped looking like documentation management.\n\nIt started looking like package composition.\n\nAIC separates three actors:\n\n```\nProvider package\n      │\n      │ declares agent-facing assets\n      ▼\nHost repository\n      │\n      │ exposes them through actual harness loading paths\n      ▼\nCoding agent\n```\n\nA **Provider** is a package that supplies agent-facing context.\n\nA **Host** is the repository consuming that package.\n\nThe provider ships its agent-facing source with the package:\n\n```\nprovider-package/\n├── agent-index.json\n├── AGENTS.md\n└── skills/\n```\n\nA minimal manifest might look like:\n\n```\n{\n  \"schema\": \"agent-index/v1\",\n  \"package\": \"@scope/schema-sdk\",\n  \"version\": \"0.14.0\",\n  \"summary\": \"Declarative schema toolkit\",\n  \"manual\": \"AGENTS.md\",\n  \"skills\": [\n    {\n      \"name\": \"schema-design\",\n      \"src\": \"skills/schema-design\"\n    }\n  ],\n  \"instanceConfig\": {\n    \"source\": \"declarative\",\n    \"readFrom\": \"schema.config.json\",\n    \"format\": \"json\",\n    \"fields\": [\"runtime\", \"validation\"]\n  }\n}\n```\n\n`agent-index.json`\n\nis not another manual.\n\nIt declares:\n\n```\nidentity\nversion\ncanonical manual\ndiscoverable assets\nhost-resolved facts\n```\n\nThe useful change for me is that the maintenance contract becomes declarative.\n\nInstead of repeatedly telling an agent:\n\n```\nUpdate the Claude and Codex instructions\nto match the latest SDK behavior.\n```\n\nit can inspect a structure closer to:\n\n```\nprovider\n  ├── canonical manual\n  ├── skills\n  ├── resolved host config\n  └── target loading semantics\n```\n\nThe update no longer depends on how well I happened to describe the maintenance task that day.\n\nThis distinction has probably been the most useful part of AIC in actual use.\n\nNot all agent-facing assets should cross the package boundary in the same way.\n\n| Class | Example | Operation |\n|---|---|---|\nIndex |\nidentity, version, pointers, resolved config | inject |\nReferenced |\nmanuals, detailed rules | keep with provider |\nMaterialized |\nharness-discovered skills | copy deterministically |\n\n```\n                  ┌── Index  ─────▶ inject\nProvider package ─┼── Manual ─────▶ reference\n                  └── Skill  ─────▶ materialize\n```\n\nI originally wanted one mechanism for all three.\n\nActual loading semantics made that abstraction wrong.\n\nCopying a manual into the host creates two independently changing truths.\n\n```\ninstalled package   v0.14\ncopied manual       v0.13\n```\n\nI've hit enough package version-skew problems elsewhere that I don't want to recreate the same class of bug in the agent-context layer.\n\nHere it is worse than ordinary stale documentation.\n\n**A stale instruction consumed by an agent that can edit code and run commands is executable misinformation.**\n\nThe agent may not be hallucinating at all.\n\nIt may be behaving perfectly according to the wrong version.\n\nSo the canonical manual stays with the installed package.\n\nThe host stores a pointer, not another copy.\n\nIn practice, this has been one of the more durable AIC decisions: upgrading the package does not require another manual copy to somehow remain synchronized.\n\nSkills are different.\n\nIf a harness discovers a skill only by scanning a particular directory, mentioning its package path is not equivalent to putting it where the harness looks.\n\nThe asset needs physical presence.\n\nSo the rule I use is:\n\nReference when read access is enough. Materialize when discovery requires presence.\n\nThat is more useful than either \"copy everything\" or \"never copy.\"\n\nContext placement should follow actual loading semantics, not an aesthetically uniform abstraction.\n\nOf the AIC decisions I've been testing, this asymmetry is one of the ones I currently trust most.\n\nEach provider contributes a small namespaced block to the host index.\n\n```\n### Agent index: `@scope/schema-sdk` v0.14.0\n\n- Manual: read `node_modules/@scope/schema-sdk/AGENTS.md`\n- Skills: managed under the harness discovery path\n- Host config: validation=strict\n```\n\nSeveral providers can coexist:\n\n```\nAGENTS.md\n│\n├── human-owned content\n├── @scope/package-a\n├── @scope/package-b\n└── @scope/package-c\n```\n\nThe central invariant is:\n\nA provider owns its namespace, not`AGENTS.md`\n\n.\n\nUpdating package B may update B's block.\n\nIt may not:\n\n```\nrewrite human content\nmove package A\nmodify package C\nregenerate the whole file\n```\n\nMaterialized assets follow the same rule: each provider gets its own collision-safe namespace.\n\nThis is also something I've been able to test rather than only describe.\n\nIn the implementations I'm using, foreign provider blocks are preserved rather than normalized into the current provider's representation. Repeating a sync with the same input is tested as a no-op. Providers can also share lock state without one provider flattening another provider's private fields.\n\nThose details are intentionally boring.\n\nBut they are the difference between saying \"multiple providers can coexist\" and actually letting them coexist.\n\nThe packages do not need pairwise integrations.\n\nPackage A does not need to know package B exists.\n\nPackage B does not need a plugin for package C.\n\nThey compose because they share an ownership rule.\n\n**Coordination is expensive. Namespaces are cheap.**\n\nThis is the point where AIC stopped feeling like a synchronizer to me.\n\nIt started feeling like a package protocol.\n\nAIC is not an argument against `.claude/`\n\n, `.codex/`\n\n, or other harness-specific locations.\n\nI use them because they are useful.\n\nThe problem was maintaining them independently.\n\nI want:\n\n```\n                       ┌── AGENTS.md\n                       │\nprovider source ───────┼── Claude adapter\n                       ├── Codex adapter\n                       ├── skill discovery adapter\n                       └── other thin adapters\n```\n\nnot:\n\n```\nmanual\n├── Claude copy\n├── Codex copy\n├── Cursor copy\n└── another copy\n```\n\nHarness-specific files are **derived surfaces**.\n\nThe canonical package knowledge remains singular.\n\nThis also gives the design an escape hatch.\n\nIf a harness eventually provides a better native mechanism for consuming package-owned instructions or skills, the adapter should disappear.\n\nThe package boundary does not have to.\n\nThe adapter layer is expendable. The boundary declaration is not.\n\nThat distinction matters because harness behavior will probably change faster than package contracts.\n\nAIC currently has lifecycle operations roughly like:\n\n```\nagent-index sync\nagent-index check\nagent-index remove\n```\n\nThe most important property is idempotence.\n\n```\nsame provider\nsame version\nsame source\nsame managed host state\n       │\n       ▼\n     no-op\n```\n\nRunning `sync`\n\ntwice with identical inputs should not produce a second write, timestamp churn, or Git diff.\n\nFor materialized assets, AIC tracks both sides:\n\n```\nprovider source ── hash ──▶ sourceHash\nhost copy       ── hash ──▶ destHash\n```\n\nThat distinguishes:\n\n```\nprovider upgraded\nhost copy locally edited\nnothing changed\n```\n\nThose states should not all result in \"copy again.\"\n\nThe original asset is materialized byte-for-byte. Provenance sits beside it rather than being injected into skill frontmatter, scripts, or templates.\n\nI don't want sophisticated reconciliation here.\n\nI want deterministic ownership with boring failure modes.\n\nThere is another reason I care about determinism:\n\n**agents are maintainers too.**\n\nA human can often infer that two slightly different layouts represent roughly the same convention.\n\nAn agent benefits more from:\n\n```\none format\none ownership rule\none lifecycle\none source of truth\n```\n\nThe easier the maintenance structure is to inspect mechanically, the less the next agent session has to reconstruct from prose.\n\nThis is one place where implementation made the tradeoff clearer.\n\nA protocol can define what should be synchronized without guaranteeing that every synchronization happens immediately.\n\nI've had cases where a package version and its managed agent state temporarily diverged because a manual step was missed.\n\nThat is exactly the class of problem AIC is intended to make detectable.\n\nIt is also evidence that declaring the protocol does not magically remove its maintenance cost.\n\nThe current split is deliberate:\n\n| Operation | Responsibility |\n|---|---|\n`preflight` |\ncheap version-staleness repair |\n`check` |\nfull version and integrity verification |\n`sync` |\nexplicit verification and regeneration |\n\nThe common path stays cheap.\n\nThe stronger path stays explicit.\n\nI prefer that to turning every CLI startup into a full filesystem integrity scan.\n\nI commit the generated index, materialized skills, and lock/provenance state.\n\nA change like:\n\n```\n- ### Agent index: `@scope/schema-sdk` v0.13.0\n+ ### Agent index: `@scope/schema-sdk` v0.14.0\n```\n\nchanges what the agent can discover.\n\nA changed materialized skill can change what the agent can do.\n\nI want those changes visible beside the dependency update that caused them.\n\nSo I think of AIC output more like this:\n\n| Artifact | Reviewable state |\n|---|---|\n| lockfile | dependency resolution |\n| generated schema | structural contract |\n| migration plan | intended transition |\n| agent index / skill | agent operating context |\n\n**Generation isn't the problem. Invisible generation is.**\n\nKeeping generated state fresh naturally leads to automatic repair.\n\nThis is where I've become deliberately conservative.\n\nI don't want dependency installation to silently rewrite host-owned files.\n\nI also don't want the first execution of an SDK CLI to decide by itself that the repository has opted into agent integration.\n\nSo AIC distinguishes adoption from maintenance.\n\n```\nfirst encounter\n    └──▶ warn / explicit sync\n\nexisting provider + stale version\n    └──▶ repair own namespace\n\nmanaged content locally edited\n    └──▶ preserve + warn\n\nCI / read-only filesystem\n    └──▶ don't mutate\n\nremoved or disabled provider\n    └──▶ stay removed\n```\n\nThe invariant is:\n\nAutomation may maintain established ownership. It should not invent ownership.\n\nThere is a tradeoff.\n\nPreflight needs an execution opportunity.\n\nIf a dependency is upgraded but the relevant provider CLI has not run yet, materialized state can temporarily remain stale.\n\nI accept that window today.\n\nThe alternative would be making package installation mutate the host automatically, which I currently consider the worse ownership boundary.\n\nTeams that need a stricter guarantee can run `check`\n\nexplicitly or in CI.\n\nSo preflight does not eliminate drift.\n\nIt makes the common repair path cheap while leaving full integrity verification explicit.\n\nThis also removes another piece of my old workflow.\n\nI no longer want this:\n\n```\nPlease update the agent files after this SDK change.\n```\n\nto be part of the development procedure.\n\nIf the relationship is structural, the update rule should be structural too.\n\nThere is an important qualification.\n\nThe providers I'm using AIC with today are part of the same development environment.\n\nI control both sides of the protocol.\n\nThat gives me something useful: I can test whether independently versioned packages actually compose through the same rules.\n\nIt does not yet prove that unrelated third-party package authors will adopt them.\n\nSo today I would describe AIC as a **working convention inside one ecosystem**, not an ecosystem-wide standard.\n\nThe distinction matters because much of the eventual value of a protocol comes from network effects.\n\nThat is the part I have not demonstrated yet.\n\nThere are a few other current assumptions.\n\nA manual that stays inside the installed package is only useful once the dependency is actually available.\n\nOn a fresh clone before dependency installation, the pointer can temporarily lead nowhere.\n\nI currently accept that because the reference is meant to describe the installed package state.\n\nIt does mean AIC is not a substitute for dependency availability.\n\nAIC relies on an entry point the harness already loads — for example `AGENTS.md`\n\n, an import into it, or a harness-specific discovery directory.\n\nIt does not solve \"how does every possible coding agent discover AIC?\" from first principles.\n\nThat is intentional.\n\nI would rather adapt to real loading behavior than introduce another mandatory bootstrap mechanism.\n\nA referenced manual is information.\n\nA materialized skill can influence what an agent actually does.\n\nThat makes third-party providers a different trust problem from packages I control myself.\n\nContent hashes tell me whether an asset changed.\n\nThey do not answer who should be trusted to supply that asset.\n\nThat is one of the areas I would want to make more explicit before treating `agent-index/v1`\n\nas a third-party ecosystem contract.\n\nAgent harnesses are moving quickly.\n\nNative packaging for instructions, skills, or package-owned agent context may eventually absorb some of what AIC adapters do today.\n\nIf that happens, I don't want to defend the current synchronization machinery for its own sake.\n\nThe parts I expect to survive are smaller:\n\n```\ndeclare the agent-facing package boundary\n\nown only your namespace\n\nkeep canonical knowledge version-bound\n\nseparate reference from discovery-required materialization\n\nmake derived state deterministic and reviewable\n\nrespect prior host ownership decisions\n```\n\nThe adapter layer is expendable.\n\nThe boundary declaration is the interesting part.\n\nThat is also why I don't want to freeze the schema too early.\n\nBefore asking unrelated providers to adopt it, I would rather make the convention boring inside the repositories I already operate:\n\n```\nfewer drift incidents\nfewer manual repair instructions\nfewer conventions that exist only in my head\n```\n\nIf that keeps working, the format has evidence behind it.\n\nIf the ecosystem converges on a better native mechanism, AIC should become a thin adapter to that mechanism rather than compete with it.\n\nThe parts I currently think are structural:\n\nThe parts I expect to change:\n\n`agent-index.json`\n\nschemaFor a while, I thought I needed a better way to tell coding agents to keep `.claude/`\n\n, `.codex/`\n\n, manuals, and skills synchronized.\n\nEventually I realized that the repeated instruction was itself the missing specification.\n\nPackages already know how to introduce themselves to programs.\n\nAIC is my attempt to give them a small, composable way to introduce themselves to coding agents.", "url": "https://wpnews.pro/news/aic-packages-need-an-interface-for-coding-agents", "canonical_source": "https://dev.to/gyu07/aic-packages-need-an-interface-for-coding-agents-562o", "published_at": "2026-08-10 06:57:18+00:00", "updated_at": "2026-08-10 07:17:31.243268+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools"], "entities": [], "alternates": {"html": "https://wpnews.pro/news/aic-packages-need-an-interface-for-coding-agents", "markdown": "https://wpnews.pro/news/aic-packages-need-an-interface-for-coding-agents.md", "text": "https://wpnews.pro/news/aic-packages-need-an-interface-for-coding-agents.txt", "jsonld": "https://wpnews.pro/news/aic-packages-need-an-interface-for-coding-agents.jsonld"}}