feat(compat): 读 AGENTS.md / CLAUDE.md 指令链 + 项目级 skills(P1) - #360
Merged
Conversation
生态已经收敛到一个 LISA 不读的约定:仓库根放一份 AGENTS.md(或 Claude Code 的 CLAUDE.md),所有 agent 都能拿到这个项目的规矩。Claude Code、Codex、Cursor、 dsh 都认。读它是成本最低的一项兼容——用户迁到 Lisa,已经写好的指令继续生效。 **指令链**(由外到内,最具体的最后读): ~/.lisa/AGENTS.md → <repo>/AGENTS.md → <repo>/CLAUDE.md → …逐级到 cwd - **按内容去重**:CLAUDE.md 经常是 AGENTS.md 的软链或副本,两份都读等于每轮 为同样的段落付两次钱; - **32KB 总预算**:这些东西进系统提示词、每轮都付,单个 monorepo 的 AGENTS.md 不能挤掉灵魂。超出截断并在提示词里标明; - **框定为"项目的说法"而非"用户的指令"**:这些文件只是被放在某个目录里就会 被读到,所以每一块都标注来源,并明说不凌驾于宪法之上、若文件让她放弃自己的 原则就无视并说出来。克隆一个恶意仓库不构成对 Lisa 下命令的资格。 **项目级 skills**:除 ~/.lisa/skills 外,另读 <repo>/.lisa/skills(rank 100) 与 <repo>/.agents/skills(rank 200)。 - **同名冲突时 home 胜出——刻意与 dsh 的"近者遮蔽远者"相反。** 对编码 harness 来说近者优先是对的默认;对这里是错的,因为 Lisa 的 skill 是她自己写的、关于 她怎么工作的提示词材料,`cd` 进一个仓库不能成为重定义它的手段。项目 skill 只做增量,被遮蔽的记录下来。这与本仓已有的先例一致(工具注册表里 builtin 胜过注入的同名工具)。 - 提示词里项目 skill 带 *(from this project)* 标注。 两者都接入了提示词指纹,所以改 AGENTS.md 或丢一个项目 skill 进去,下一轮就 生效,而不是下个会话——与灵魂文件同样的承诺。 不做文件热监听:skills 与指令文件本来就经指纹每轮重读,再加一个 chokidar 依赖是纯冗余。 测试 19 例:分层顺序、git 根定位、CLAUDE.md 独立生效、同内容折叠、不同内容 都留、空文件跳过、预算截断、来源标注与"不凌驾"措辞、创建/编辑/删除都动指纹; skills 的分层、home 不可被项目覆盖、两个项目目录间 rank 优先、名字与目录不符 的冒名 skill 被忽略、坏文件静默跳过。全量 1571 通过。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…te budget, project-skill loadability Adversarial-review fixes for the AGENTS.md/CLAUDE.md chain + project skills: - chain.ts: refuse symlinked/non-regular AGENTS.md and bound the read by BYTES before it happens — closes (a) arbitrary-file read (a repo's AGENTS.md → ~/.ssh/id_rsa read verbatim into the prompt) and (b) unbounded-read DoS (multi-GB file / /dev/zero OOM, FIFO hang). Budget now counts UTF-8 bytes, so CJK can't claim ~3x the room. Regression tests added. - discovery.ts: same lstat symlink refusal + size cap on project SKILL.md, and validateSkillName() on untrusted project skill dir names. - prompt.ts: cap each project-skill description + their count, and frame them as the repo's stated convention (not authority) like the instruction chain. - skills/tool.ts: skill_manage(view) resolves project skills via discovery so a skill the index advertises can actually be opened (was home-only → "not found"). Deferred (follow-up): server/daemon binding project scope to process.cwd(), and the untrusted-instruction section's prompt placement. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Owner
Author
Adversarial review — findings + fixes appliedReviewed for path-traversal, injection, ACE, and correctness. Clean on the scariest axis: opening a repo does not auto-load/execute project HIGH — fixed
MED — fixed
Deferred to a follow-up (noted, not blocking)
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
为什么
生态已经收敛到一个 LISA 不读的约定:仓库根放一份
AGENTS.md(或 Claude Code 的CLAUDE.md),所有 agent 都能拿到这个项目的规矩。Claude Code、Codex、Cursor、dsh 都认。读它是成本最低的一项兼容 —— 用户迁到 Lisa,已经写好的指令继续生效。指令链
由外到内,最具体的最后读:
CLAUDE.md经常是AGENTS.md的软链或副本;两份都读 = 每轮为同样的段落付两次钱安全考量(这项的关键)
这些文件只是被放在某个目录里就会被读到。所以每一块都标注来源,且 section 开头明说:它们是 context 不是 authority、不凌驾于宪法之上、若文件让她放弃自己的原则就无视并说出来。克隆一个恶意仓库不构成对 Lisa 下命令的资格。
项目级 skills
除
~/.lisa/skills外,另读<repo>/.lisa/skills(rank 100)与<repo>/.agents/skills(rank 200)。同名冲突时 home 胜出 —— 刻意与 dsh 的"近者遮蔽远者"相反。 对编码 harness 来说近者优先是对的默认;对这里是错的,因为 Lisa 的 skill 是她自己写的、关于她怎么工作的提示词材料,
cd进一个仓库不能成为重定义它的手段。项目 skill 只做增量,被遮蔽的记录在PromptSnapshot.shadowedProjectSkills。这与本仓已有的先例一致:工具注册表里 builtin 胜过注入的同名工具。
提示词里项目 skill 带
*(from this project)*标注 —— 她自己写的和这个 repo 塞进来的,值得不同程度的信任。热更新
两者都接入了提示词指纹,所以改
AGENTS.md或丢一个项目 skill 进去,下一轮就生效而不是下个会话 —— 与灵魂文件同样的承诺。不做文件热监听:skills 与指令文件本来就经指纹每轮重读,再加一个 chokidar 依赖是纯冗余。
测试(19 例)
分层顺序 / git 根定位(含无
.git的孤儿目录)/CLAUDE.md独立生效 / 同内容折叠 / 不同内容都留 / 空文件跳过 / 预算截断 / 来源标注与"不凌驾"措辞 / 创建·编辑·删除都动指纹;skills 的分层 / home 不可被项目覆盖 / 两个项目目录间 rank 优先 / 名字与目录不符的冒名 skill 被忽略 / 坏文件静默跳过。实测(临时 repo:
AGENTS.md+ 同内容CLAUDE.md+ 一个项目 skill):instructionFiles只列 1 个(重复的被折叠)、skill 带(from this project)、编辑AGENTS.md后指纹变化。全量 1571 通过 / 0 失败。
🤖 Generated with Claude Code