English summary — teamai's UserPromptSubmit hook persists the full text of the user's
prompt to two plaintext files on disk:
~/.teamai/debug.log ([prompt=<full text>]) and
~/.teamai/dashboard/events.jsonl ("promptSummary":"<full text>").
The field is named promptSummary, but it stores the complete prompt, not a summary.
Consequence: any credential or token a user pastes into an AI tool prompt is written to disk in
clear text and kept indefinitely — debug.log has no rotation. Verified blast radius: this does
not reach the team repo (stats/*.yaml holds only aggregate counters, no prompt text), but the
two local files are enough. Suggested fix: stop persisting prompt content (store length, a hash, or
a redacted form), or make it opt-in; and rename/truncate the field so it matches its name.
Description
teamai 的 UserPromptSubmit 钩子会把用户 prompt 的完整原文写进两个本地明文文件。
~/.teamai/debug.log:
2026-09-19T11:28:26.798Z [DEBUG] dashboard: recorded prompt_submit for session <session-id> [prompt=<prompt 全文>]
~/.teamai/dashboard/events.jsonl:
{"type":"prompt_submit","timestamp":"...","sessionId":"...","tool":"workbuddy","cwd":"...","promptSummary":"<prompt 全文>"}
注意 events.jsonl 里的字段名是 promptSummary,但它存的不是摘要,而是一字不差的全文(本次实测:prompt 只有一句话,落盘内容与该句完全一致)。这个命名会误导使用者以为记录的是脱敏摘要,从而低估风险。
为什么这是个问题
用户把敏感信息粘进 AI 工具的对话框是很常见的操作——「这是我的私人令牌」「这是数据库密码」「帮我改一下这个连接串」。而在装了 teamai 的机器上,这个动作会把凭据永久留在磁盘上:
- 用户不会有任何提示,也不会预期"提问内容被落盘";
~/.teamai/debug.log 是持续追加的调试日志,没有轮转,历史越积越长;
- 这两个文件默认就是普通用户可读,任何能读用户目录的进程/备份/同步工具都能拿到;
- 用户发现后能做的事只有一件——吊销凭据。因为日志、会话记录、各类 trace 里已经散落了多份副本,逐个清理既不完整也不现实。
本次的真实触发场景:用户为了让我通过 API 关闭一个 PR,在对话里贴了 Gitee 私人令牌。该令牌随即出现在上述两个文件中。排查时还有一层困扰——无法从落盘内容判断是谁写的,因为钩子记录的是 prompt 本身,看起来就像"某段代码把令牌写进了日志"。
已核实的爆炸半径(供维护者参考)
好消息是它没有扩散到团队仓库:
# team-repo 工作区、全部历史、远端 master 均无命中
git grep -I "<token>" $(git rev-list --all) # 空
git grep -I "<token>" origin/master # 空
stats/<user>.yaml 只存聚合计数,不含 prompt 文本:
username: C
updatedAt: 2026-09-19T11:03:31.693Z
skills: {}
interventions:
sessions: 5
interrupt: 0
toolReject: 0
correction: 0
prompts: 11
tokens:
input: 0
output: 0
cacheRead: 0
cacheCreation: 0
也就是说:聚合成 prompts: 11 是对的、也是有用的,问题在于把内容也一起写进了本地文件。
Reproduction
- 在已安装 teamai 的环境里,通过任意受管工具(本机为 WorkBuddy)提交一条包含唯一字符串的 prompt,例如
MY_UNIQUE_MARKER_9f3c。
- 检索:
grep -rl "MY_UNIQUE_MARKER_9f3c" ~/.teamai/
- 命中结果:
~/.teamai/debug.log
~/.teamai/dashboard/events.jsonl
- 查看命中行:两者都包含该标记的完整 prompt 文本,
events.jsonl 里字段名为 promptSummary。
Environment
- OS: Windows 11 25H2 (10.0.26200)
- Node.js:
v22.22.2
- teamai:
0.24.0
- Provider: Gitee
- AI tool(s): WorkBuddy(钩子对所有
UserPromptSubmit 启用工具都生效)
Logs
落盘内容(敏感串已打码)
~/.teamai/debug.log:
2026-09-19T11:28:26.798Z [DEBUG] dashboard: recorded prompt_submit for session <sid> [prompt=<REDACTED-TOKEN> 这是我的私人令牌。]
~/.teamai/dashboard/events.jsonl:
{"type":"prompt_submit","timestamp":"2026-09-19T11:28:26.777Z","sessionId":"<sid>","tool":"workbuddy","cwd":"d:\\workbuddyworkspace","promptSummary":"<REDACTED-TOKEN> 这是我的私人令牌。"}
注意 promptSummary 与原始 prompt 逐字相同。
Suggested fix
按破坏性从小到大:
- 字段改名 + 截断。 若确实要留 prompt,
promptSummary 就应当真的是摘要(例如前 N 个字符 + 省略标记),不要存全文。命名与行为不一致是最容易误导的一环。
- 降级为可度量信号。 仪表盘真正需要的似乎只是计数(
prompts: 11 这类聚合已经足够且有价值)。可以只记录长度 + 哈希,既能统计、又能对同一 prompt 去重,还不落内容。
- 默认不落内容,需要时显式开启。 例如
sharing.dashboard.capturePromptText: false 作为默认,让需要排查问题的用户自己打开。
- 加轮转与权限收紧。
debug.log 目前只增不减,且包含 prompt 原文。给它加大小上限/轮转,并在创建时收紧文件权限,至少能限制窗口期。
- 文档里写明这一点。 无论最终选哪个方案,"提问内容会被写到哪里"都应当让用户能查到——本次排查里这层信息完全缺失。
Description
teamai 的
UserPromptSubmit钩子会把用户 prompt 的完整原文写进两个本地明文文件。~/.teamai/debug.log:~/.teamai/dashboard/events.jsonl:{"type":"prompt_submit","timestamp":"...","sessionId":"...","tool":"workbuddy","cwd":"...","promptSummary":"<prompt 全文>"}注意
events.jsonl里的字段名是promptSummary,但它存的不是摘要,而是一字不差的全文(本次实测:prompt 只有一句话,落盘内容与该句完全一致)。这个命名会误导使用者以为记录的是脱敏摘要,从而低估风险。为什么这是个问题
用户把敏感信息粘进 AI 工具的对话框是很常见的操作——「这是我的私人令牌」「这是数据库密码」「帮我改一下这个连接串」。而在装了 teamai 的机器上,这个动作会把凭据永久留在磁盘上:
~/.teamai/debug.log是持续追加的调试日志,没有轮转,历史越积越长;本次的真实触发场景:用户为了让我通过 API 关闭一个 PR,在对话里贴了 Gitee 私人令牌。该令牌随即出现在上述两个文件中。排查时还有一层困扰——无法从落盘内容判断是谁写的,因为钩子记录的是 prompt 本身,看起来就像"某段代码把令牌写进了日志"。
已核实的爆炸半径(供维护者参考)
好消息是它没有扩散到团队仓库:
stats/<user>.yaml只存聚合计数,不含 prompt 文本:也就是说:聚合成
prompts: 11是对的、也是有用的,问题在于把内容也一起写进了本地文件。Reproduction
MY_UNIQUE_MARKER_9f3c。events.jsonl里字段名为promptSummary。Environment
v22.22.20.24.0UserPromptSubmit启用工具都生效)Logs
落盘内容(敏感串已打码)
~/.teamai/debug.log:~/.teamai/dashboard/events.jsonl:注意
promptSummary与原始 prompt 逐字相同。Suggested fix
按破坏性从小到大:
promptSummary就应当真的是摘要(例如前 N 个字符 + 省略标记),不要存全文。命名与行为不一致是最容易误导的一环。prompts: 11这类聚合已经足够且有价值)。可以只记录长度 + 哈希,既能统计、又能对同一 prompt 去重,还不落内容。sharing.dashboard.capturePromptText: false作为默认,让需要排查问题的用户自己打开。debug.log目前只增不减,且包含 prompt 原文。给它加大小上限/轮转,并在创建时收紧文件权限,至少能限制窗口期。