AI 코딩 에이전트를 위한 Agent.lock 파일이 있어야 하지 않나요?

hackernews | | 🔬 연구
#anthropic #claude #gemini #gpt-5 #review
원문 출처: hackernews · Genesis Park에서 요약 및 분석

요약

현재 개발팀 저장소에는 Cursor, Claude Code, Windsurf, Copilot 등 각각 고유한 설정 파일 구조를 가져 8개 이상의 설정 경로가 공존하고 있으며, 팀원들이 서로 다른 AI 모델(Rust 백엔드는 Opus 4.6, 프론트엔드는 GPT-5.3)을 사용하면서 코딩 에이전트가 만든 설계 결정이 완전히 검증되지 않은 상태로 병합되고 있다. 2600개 이상의 AI 스킬 중 340개 이상이 악성코드로 밝혀졌지만, 어떤 스킬이 활성 상태였는지 세션 종료 후 기록이 남지 않아 보안 감사가 불가능하며, MCP 서버의 도구 설명에는 서명이나 버전 관리 기능이 없어pins가 불가능하다. 다중 에이전트 워크플로우가 프로덕션으로 확대되면서 리뷰 에이전트가 보는 것은 오직.diff뿐이어서 어떤 모델 버전, 스킬, MCP 서버가 코드 작성에 관여했는지 알 수 없는 상황이다. 저자는 패키지-lock.json과 같은 개념으로 agent.lock 파일을 제안하며, 이를 통해 모델 버전, 스킬 해시, 규칙 파일 무결성, MCP 서버 도구 설명 해시 등을 고정하고 CI에서 감지·강제할 수 있도록 해야 한다고 주장한다.

본문

Where is My agent.lock file? We pin every package to a hash. We let AI agents run with whatever they want. Disclaimer: Opinions expressed are solely my own and do not express the views or opinions of my employer or any other entities with which I am affiliated to. There’s a philosophical question buried in every lockfile, and most developers probably know about it. When you run npm install and it reads from package-lock.json, what’s actually happening isn’t just “installing dependencies.” It’s an act of reproducing a known state. Someone, at some point, made a set of decisions about which versions of which libraries to trust. The lockfile is the artifact of those decisions. It exists so that every subsequent build doesn’t have to re-make them, and so that when something goes wrong, you can trace back to the exact combination of inputs that produced the problem. Reproducibility isn’t a convenience. It’s how you debug. It’s how you audit. It’s how you answer the question “why does this work the way it does?” six months from now when nobody remembers. I keep coming back to this because I think we are quietly abandoning this principle in the most consequential part of modern software development. And the thing that bothers me most isn’t that nobody has solved it. It’s that almost nobody has noticed. The madness in your root directory Open any active repository at a mid-size engineering org right now and look at the root directory. If the team uses more than one AI coding tool, and most do, you’ll find some combination of this: .cursor/ rules/ .claude/ skills/ .windsurf/ rules/ .github/copilot-instructions.md .opencode/ .zed/ CLAUDE.md AGENTS.md GEMINI.md Every AI coding tool has invented its own configuration surface. Its own folder, its own rules format, its own discovery mechanism. None of them talk to each other. An engineering manager recently described his repo as having eight different config paths for what is fundamentally the same thing: telling the AI how to behave. His solution? A shell script that hard-links a single markdown file into every tool’s expected location. That’s where we are. Shell scripts holding the config layer together with string and duct tape. AGENTS.md is emerging as a cross-tool standard with adoption across 60,000+ open source projects, which is encouraging. But the fragmentation is still bad enough that people are writing symlink scripts just to keep their instructions consistent across Cursor, Claude Code, Windsurf, and Copilot. That’s the visible symptom. The deeper issue is what you can’t see in the file tree: every developer on that team is running a completely different agent stack under the hood, and there’s no mechanism to detect, enforce, or even record the divergence. Same repo, different universes Think about a pretty ordinary week at a pretty ordinary company. The backend team is building an API service in Rust. The frontend team is building the dashboard in TypeScript. A platform engineer is writing infrastructure-as-code. The backend engineer chose Claude Code backed by Opus 4.6, deliberately. Opus reasons more carefully through ownership semantics and lifetime annotations. For unsafe Rust, where a subtle mistake compiles fine but causes memory corruption at runtime, that deeper reasoning isn’t a luxury. It’s a material input to code safety. The frontend engineer is on Cursor backed by GPT-5.3, because for rapid TypeScript UI iteration, the model’s speed and pattern completion are more valuable than deep reasoning. Fair choice. The platform engineer hasn’t updated their configuration in two months and is still running Sonnet 4.5. All three are committing to the same monorepo. All three are producing code shaped by models with fundamentally different reasoning characteristics, different strengths, different failure modes. The Opus sessions handle Rust lifetime analysis differently than GPT would. The Sonnet 4.5 sessions produce different patterns from both. These aren’t editor preferences. The model is making architectural decisions, choosing patterns, selecting approaches. It’s a core input to the code. And it’s completely unpinned. Everything else that’s unpinned Models are just one dimension. Here’s the rest of the stack that’s silently diverging across your team. Skills. The SKILL.md ecosystem crossed 2,600 published skills earlier this year, spanning Claude Code, Codex, Cursor, and a growing list of platforms. They’re the extension ecosystem for AI agents, portable instruction sets that teach an agent specific workflows. Developers install them casually: browse a registry, grab one that looks useful, start coding. Researchers have already found over 340 malicious skills harvesting credentials, exfiltrating environment variables, or injecting behavioral guidance that subtly shapes every line of code the agent writes. When a developer loads a skill, it becomes part of the agent’s instruction set. When the session ends, no record of which skills were active survives. This can be however managed / controlled at the enterprise Rules files. CLAUDE.md and .cursor/rules and AGENTS.md sit in the repo, which creates the illusion they’re managed. They’re not. They’re configuration for an autonomous system disguised as documentation, and nobody treats them with the rigor that deserves. They drift. They go stale. They contain instructions from engineers who left the company months ago, still telling the agent to trust certain internal packages, skip certain validation, use architectural shortcuts that made sense in a different threat model. The agent follows them faithfully, because that’s what agents do. MCP servers. Each developer connects whichever MCP servers they’ve set up locally. The MCP specification doesn’t require tool description signing or versioning, so there’s no way to pin or verify the behavioral instructions these servers provide. One developer has a community-built database tool that subtly influences how the agent constructs queries. Another has no MCP servers at all. Same repo, same prompt, different context, different code. None of this is visible to anyone. Not to the developer, not to the reviewer, not to CI, not to your security team. Why pinning matters (and it’s not just consistency) The obvious argument for pinning is consistency: everyone on the team should run the same approved configuration. That’s true, but it’s the least interesting reason. The more important reason is that different models and tools are genuinely better at different things, and those differences have real consequences for code quality and security. Pinning isn’t about restriction. It’s about making the choice deliberate. You might specifically want Opus 4.6 for the Rust backend because its deeper reasoning catches lifetime and ownership issues that lighter models miss. That’s not a preference. It’s an engineering decision with safety implications, and it should be documented, reviewed, and enforced the same way you’d enforce a linter configuration or a minimum test coverage. The same logic applies to skills. A skill designed for secure authentication flows should be a pinned, reviewed, approved dependency for any PR touching auth, not something one developer happens to have installed and another doesn’t. A skill that generates database migrations should be version-locked so every developer’s agent produces migrations with the same conventions. This is exactly how we think about library dependencies. We don’t let one developer use ORM version 2.x and another use 3.x in the same project. We pin it. We review the upgrade. We test the change. The same discipline needs to apply to the tools that are now writing our code. Where its actually going to be serious: agent-to-agent You could argue that configuration divergence is manageable today because a human still reviews the output. Even a quick scan of a diff catches the worst problems. A thin safety net, but it exists. That net is disappearing faster than most people realize. Multi-agent workflows are moving from demos into production. A planning agent decomposes tasks, Coding agents implement the pieces, Review agents evaluate the PRs. Anthropic’s own research shows autonomous Claude Code sessions nearly doubled in duration between late 2025 and early 2026, with tail sessions running over 45 minutes before a human touches anything. AI-powered code review tools like CodeRabbit, or even Claude are already handling PR evaluation at scale in real organizations. Question for the security teams to think about: what does your review agent actually know about the coding agent’s session? The answer: the diff. That’s it. The review agent doesn’t know which model version wrote the code. It doesn’t know which skills were active. It doesn’t know which MCP servers were connected or what tool descriptions shaped the agent’s decisions. It can evaluate whether the code looks correct. It cannot evaluate whether the code was produced under conditions you’d trust. That’s not code review. That’s pattern matching on the output of a black box. What an agent.lock looks like A lockfile in the dependency world does three things: it pins exact versions so everyone builds the same way, it enables reproducibility so you can rebuild any past state, and it makes changes auditable so a version bump is a visible, reviewable event. An agent.lock does the same, for the agent stack. # agent.lock # Pinned agent configuration for this repository # Generated: 2026-04-10T14:32:00Z [model] provider = "anthropic" default = "claude-opus-4-6-20260205" min_version = "claude-sonnet-4-6-20260410" [model.overrides] # Deliberate model choices per codebase area "src/rust/**" = { model = "claude-opus-4-6-20260205", reason = "deep reasoning for unsafe/lifetime analysis" } "src/frontend/**" = { model = "claude-sonnet-4-6-20260410", reason = "faster iteration for UI components" } [skills] "frontend-design" = { version = "2.1.0", publisher = "anthropic/official", hash = "sha256:b4c2d8e...", verified = true } "auth-patterns" = { version = "1.0.3", publisher = "community/securecoder", hash = "sha256:f7e1a3b...", verified = false, review_status = "approved-2026-03-20" } "db-migrations" = { version = "0.8.1", publisher = "community/dbtools", hash = "sha256:a1c9e2f...", verified = true } [rules] "CLAUDE.md" = { hash = "sha256:c9d4e1f...", last_reviewed = "2026-03-15", reviewed_by = "@lead-engineer" } [mcp_servers] "github" = { version = "1.4.0", publisher = "github/official", tool_description_hash = "sha256:d2f5b9a..." } "internal-docs" = { url = "https://internal.company.com/mcp", tool_description_hash = "sha256:e8a3c7d..." } [constraints] require_skill_verification = true allow_unverified_skills_if_reviewed = true require_rules_review_within_days = 90 block_unregistered_mcp_servers = true allow_model_fallback = false Pinning. Every component has a version and a content hash. Model, skills, rules files, MCP tool descriptions. Change any of them and the lock breaks. Enforcement. When a developer starts an agent session in this repo, the tooling checks the lockfile. Wrong model? Blocked. Unregistered skill? Blocked. MCP server with a changed tool description? Flagged, re-authorization required. Configuration isn’t documented after the fact; it’s enforced before the agent writes a single line. Auditability. CI diffs the agent.lock exactly the way it diffs package-lock.json. A PR that adds a new skill, changes the model, or connects a new MCP server shows up as a lockfile change. Reviewers see it. Security teams can gate on it. Drift detection. The lockfile becomes the source of truth for what’s approved. If a developer’s local setup drifts, they know immediately. Though it’s worth noting: the lockfile captures the approved configuration. Capturing what actually ran for a specific commit, the full runtime context, the session state, which skills fired, which MCP tools were called, that’s a related but distinct problem. It’s the difference between a menu and an order ticket, and it’s important enough that I plan to writing a separate piece about it. The agent install moment Here’s where this gets tangible. When you clone a repo and run npm install , the package manager reads the lockfile and sets up your dependency tree to match the team’s approved state. You don’t think about it. It just works. We need the same moment for AI agent configuration. youragent install agent.lock That command would configure the developer’s agent environment to match the repo’s pinned state. Pull the specified skills at the correct versions and verify their hashes. Register the allowed MCP servers. Set the model version or model overrides. Validate the rules file against its expected hash. If something doesn’t match, fail loudly, just like npm ci fails when the lockfile is out of sync. The same mechanism extends to CI, and this is where it gets really powerful. When a review agent spins up to evaluate a PR, it runs youragent install first. Now it’s not just looking at a diff in a vacuum. It has the full configuration context: which skills are approved for this repo, what behavioral instructions the rules file contains, which MCP servers the coding agent was expected to connect to. It can pull the skill definitions to understand why a coding agent chose certain patterns. It can check whether the PR’s code aligns with the conventions the pinned skills enforce. It can flag a dependency choice that matches a known bias in an unverified skill’s instructions. The review agent goes from pattern matching on syntax to reasoning about intent. And it all starts with a lockfile and an install command. What needs to happen IDE vendors need to ship lockfile support. Cursor, Claude Code, VS Code with Copilot, Windsurf. They already have all the data. The first vendor to generate and enforce an agent.lock creates the de facto standard. Same dynamic that drove lockfile adoption in package managers: one tool gets it right, and it becomes table stakes. The ecosystem needs to converge on configuration. The .cursor/ , .claude/ , .windsurf/ , .github/copilot-instructions.md , .opencode/ , .zed/ , CLAUDE.md, AGENTS.md, GEMINI.md situation is unsustainable. An agent.lock would at least give teams one canonical file for the parts that actually matter for security and reproducibility, regardless of which IDE each developer uses. The MCP spec needs tool description signing and versioning. You can’t pin what you can’t hash. Tool descriptions need to be signed, versioned, and pinnable so an agent.lock can reference a specific, verifiable snapshot of what a server exposes. The skills ecosystem needs trusted publishing. Publisher verification, content signing, version pinning, integrity hashes. PyPI learned this the hard way. npm learned it the hard way. The skills ecosystem is in its “hope nobody notices the malicious packages” phase, and we know exactly how that story ends. CI needs lockfile awareness. The same way your pipeline fails when packag

Genesis Park 편집팀이 AI를 활용하여 작성한 분석입니다. 원문은 출처 링크를 통해 확인할 수 있습니다.

공유

관련 저널 읽기

전체 보기 →