关于 dmcheck
dmcheck 是面向主持人与 Agent 的桌面角色扮演会话裁判,可确定性地检查会话转录和可选的引擎事件记录。它按桌规提供带证据的行为问题,并避免将含糊证据升级为确定指控。
主要功能
- 01依据桌规检查会话转录
- 02提供带规则引用和证据的问题
- 03监看进行中会话的问题开启与解决
- 04接收转录和事件记录输入
- 05验证桌规配置
- 06输出结构化判定和退出状态
适用场景
- 01检查会话记录中未获答复的问题
- 02发现未确认的掷骰或回合
- 03监看现场会话中的未解决问题
- 04将无效或不完整的检查交由人工审阅
MCP 相关
README 将 dmcheck-mcp 的未发布 0.6.0 源码候选版描述为只读、批处理型 stdio MCP 服务,提供 `run` 和 `rules` 工具。它接收内嵌的转录、桌规和事件记录;路径输入须位于明确允许的目录中。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
2收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| gm | array | 否 | GM 作者姓名;覆盖 charter.gm |
| ledger_path | string | 否 | |
| charter_path | string | 否 | |
| transcript_path | string | 是 |
详细介绍
dmcheck
为实时桌面游戏会话提供确定性的行为判定——运行游戏的 CI。
输入会话文字记录(以及可选的引擎事件账本)和一份桌规章程,即可获得具名判定结果——玩家提出的问题无人回应、无人确认的掷骰、未通知任何人就开始的回合、泄露到频道中的剧透、长达五分钟的冷场。每项判定都会引用其违反的章程规则,并附上证据。
Agent 从这里开始 → SKILL.md——了解何时调用、本工具的示例,以及 MUST/MUST NOT 要求。系列契约:FAMILY.md。
**冷启动探测(2026-07-24):**一个全新的 Agent 会话仅凭此仓库 URL,就在 2 条命令内完成安装并主持了一场会话;它根据文档验证了三种退出码情形,并确认未错误指控契约得到遵守(已消耗的掷骰不会产生判定)。其使用摩擦记录已随 0.1.1 发布(
--dice-bot、dmcheck charter)。**设计契约:**错误指控是不可饶恕的缺陷。只有源中观察到的证据才能形成确定判定。旧数据中的模糊情况要么不作判定,要么明确标记为
severity: advisory、provenance: inferred、confidence: low;绝不会被 R8 提升,也不会发送给通知钩子。判定路径不依赖模型,且具有确定性:相同的文字记录,每次都会得到相同的判定结果。
30 秒即可开始主持会话
$ pip install dmcheck # stdlib only, no dependencies
$ dmcheck run session.jsonl --gm "Greta"
{
"result_schema_version": "1.0",
"status": "findings",
"exit_code": 1,
"mode": "closed",
"messages": 9,
"findings": [
{"finding_id": "r2-…", "rule": "R2", "summary": "unconsumed-roll: a dice result got no correlated GM narration within threshold",
"charter": "roll_ack_within_messages=4; correlation=explicit",
"detail": "dice result from DiceBot received no correlated GM narration within 4 messages",
"evidence": {"index": 6, "author": "DiceBot", "obligation_id": "roll-42"},
"status": "open", "severity": "finding", "provenance": "observed", "confidence": "high",
"charter_digest": "sha256:...", "effective_policy": {"roll_ack_within_messages": 4, "...": "..."}},
...
],
"counts": {"R1": 1, "R2": 1, "R6": 1, "R7": 1, "R8": 1}
}
能够输出 table-kit 版本化契约的项目托管端,可使用
dmcheck run-events session-events.jsonl --gm "gm-dan",无需预先投影文字记录。严格适配器接受 JSON 数组或 JSONL 格式的 table.event/1.0 对象,并在判定证据中保留事件 ID 和关联 ID。已声明的操作不会被视为权威引擎判定,因此不会错误指控合法的反应和中断。
传输缺口、未知版本或类型,以及兼容事件流数量为零时,都会返回类型化的 incomplete 状态并以退出码 2 结束;格式错误的 v1 事件会返回 invalid 并以退出码 2 结束。消息内容经过删减时也会判为 incomplete,因为缺少文字内容无法证明不存在行为义务。此未发布的适配器固定对应 table-kit PR #11,不代表托管端认证。
当项目托管端需要共享的 table.evaluation/1.0 封装时,可为 run-events 添加 --table-evaluation。此投影包含确定性的评估标识、精确的事件证据引用、逐规则及汇总覆盖率、游标/输入摘要、公共策略摘要,以及状态/退出码映射。它始终为 self_attested;dmcheck 无法让自己的输出获得托管端权限。
文字记录格式:UTF-8 JSONL,内容为 {ts, author, content};或采用 Discord API 形状消息的 JSON 数组({timestamp, author: {username}, content}),顺序可为时间正序或倒序。作者和内容均为字符串。提供的时间戳必须是有限的非负纪元时间数字,或带时区的 ISO-8601 字符串;格式错误的时间戳会被拒绝,而不会悄悄停用基于时间的规则。源适配器应保留不可变的 id、audience、reply_to/correlation_id 和 roll_id 字段,以便 dmcheck 证明某条回应结束了哪个问题、掷骰或事件;之后 GM 的普通闲聊不会被视为回应。
规则集(七条启用规则;一个已退役的兼容 ID)
| 规则 | 触发条件 | 起源故事 |
|---|---|---|
| R1 | 明确面向 GM 的问题在阈值时间内未得到关联回应 | 一名玩家向 DM 提了一个世界观问题,结果回答问题的却是另一名玩家 |
| R2 | 真实掷骰结果在阈值时间内未得到关联的 GM 叙述 | “我命中了吗?”——一名玩家的成功攻击检定迟迟无人回应 |
| R3 | 引擎事件未得到关联的 GM 叙述 | 状态引擎判定命中,但桌上的人都没听到 |
| R4 | 一个回合开始了,但 GM 从未点名回应行动者 | “不是轮到她了吗?”——一名玩家提出了这个问题,多一个玩家都嫌多 |
| R5 | 已退役;永不触发 | 行动者 != 回合所有者,导致合法反应和插话被错误指控 |
| R6 | 配置的隐藏术语出现在 GM 消息中;普通输出只会显示其不透明 ID | 模组的秘密状态名称泄露到了叙述中 |
| R7 | 玩家等待期间,GM 超过阈值时间没有回应 | 30 秒像是在思考;五分钟就像是人不在 |
| R8 | 会话结束时仍有当前未关闭、由来源观察到的 R1–R3 义务;推断出的旧版提示不会升级 | 会话应该以明确状态结束——这正是下一场会话得以开始的条件 |
这些启用规则源自一个混合桌游团:人类和 AI 玩家、AI GM,在 Discord 上进行游戏;这些问题确实发生过,并在同一周内被编入规则。它们同样适用于人类 GM:对自己导出的游戏日志运行 dmcheck,看看你们桌上的记录呈现了什么。
保留 R5 只是为了避免旧版章程和 Agent 集成失效。它没有评估器,默认也未启用:行动者与回合所有者不同,可能表示反应、预备触发、借机攻击、传奇动作或巢穴动作、受控生物、环境行动者,或其他系统的插话。台账无法判定其是否合法。任何基于明确权威决策的替代规则都将推迟到共享的 PORT-002 事件契约;dmcheck 只会评估由此产生的沟通或恢复义务。
实时模式(0.2):裁判就在桌边
dmcheck watch 会在持续增长的会话上运行同一套引擎——输入为 stdin JSONL 或被跟踪的文件——并发出生命周期事件:当观察到的问题变得可证实,或旧版推断成为提示时(阈值时间已完全过去;不作预测),发出 OPEN;当仍在持续的情况得到解决时(引擎事件终于得到叙述),发出 RESOLVED。--notify-cmd
会针对每个由来源观察到的 OPEN 问题触发你自己的钩子;推断出的提示仍会显示在事件流中,但绝不会触发钩子。dmcheck 本身不会向任何地方发送消息。
会话结束时会运行一次封闭模式检查。session_end.open 和 open_count
只报告可采取行动的、由来源观察到的问题;不包括 R8 汇总项和推断出的提示。
问题 ID 在经过时间等可变细节变化时仍保持确定性;当轮转、截断、不完整行或顺序缺口导致覆盖不完整时,文件跟踪器会发出带类型的来源健康事件。
$ your-chat-fetcher | dmcheck watch - --gm "Rob" --notify-cmd 'notify-dm.sh'
{"event": "open", "rule": "R2", "detail": "dice result from RollBot received no correlated GM narration", ...}
{"event": "resolved", "rule": "R3", ...}
{"event": "session_end", "status": "findings", "exit_code": 1, "open": ["R1"], "open_count": 1, ...}
$ dmcheck explain R2 # the rule, its charter knobs, and the table failure that earned it
$ dmcheck lint-charter my.json # unknown keys / bad thresholds refuse loudly
实时模式的意义在于:规则所编码的每个问题,在发生当下都能得到补救——无人回应的问题、过时的掷骰、缺失的提示,都有几秒钟的窗口,及时提醒就能挽回节奏。事后检查只能告诉你昨晚出了什么问题;watch 会在玩家感受到问题之前,轻拍 GM 的肩膀提醒他。
章程是配置,不是代码
dmcheck/default_charter.json 是唯一权威的打包默认配置。它包含 schema_version、charter_version 和经过验证的 SHA-256 charter_digest;在检出目录和 wheel 中执行时,都会加载同一资源。其摘要与 schema/章程版本对锁定,因此打包的默认配置一旦更改,在声明版本迁移之前就会拒绝加载。可以覆盖其中任意配置——提示约定、冷场容忍度、骰子机器人名称、隐藏术语列表——并对其进行版本管理。隐藏术语可以是字符串(用于兼容),也可以是 {id, value} 对象;优先使用不透明的主机签发 ID。发现项、监视钩子、CLI 和 MCP 输出会隐去配置值和原始匹配片段。发送到普通输出接收端的每个摘要或关联哈希——包括评估信封、lint-charter、发现项 ID 和源指纹——均基于公开、已脱敏的策略/证据生成,并且有意不证明或承诺任何隐藏值。完整的规范摘要仅保留在可信的章程文档中。联赛或有组织的游戏项目可以像发布玩家指南一样发布章程;随后,dmcheck 就能依据它为任何游戏桌担任裁判。
$ dmcheck run session.jsonl --charter our-table.json --ledger events.jsonl
$ dmcheck rules # the rule set with definitions
$ dmcheck charter # inspect effective public policy; hidden values are redacted
$ dmcheck run session.jsonl --gm "Rob" --dice-bot "RollBot" # quick overrides, no file needed
$ dmcheck --schema # machine-readable I/O contract
$ dmcheck --pipe # batch: JSON requests on stdin, verdicts on stdout
直接调用 API 的用户可以使用 apply_charter_overrides(load_charter(), gm=["Rob"]);此辅助函数会移除先前生效的摘要,由评估器为覆盖后的章程计算摘要。若修改已生成摘要的章程却不执行此操作,系统会将其作为过期配置拒绝,而不会默默信任。
面向 Agent
- 仓库根目录中的
tool.json;--schema;用于批处理的--pipe(每行标准输入一个 JSON 请求,每行输出一个判定信封);退出代码:0无问题 ·1有发现项 ·2章程/输入不可用(诚实处理方式——转交人工) ·3用法错误(修正调用后重试)。 - MCP 服务:
dmcheck-mcp的 尚未发布的 0.6.0 源码候选版本是只读、仅支持批处理的 stdio 服务,提供run和rules工具;公开版 0.5.5 早于此契约。它仅实现现代无状态 MCP2026-07-28,不提供watch、craft、任务、资源或提示词。请参阅准确的 MCP 契约。 - MCP
run优先使用内联的 transcript/charter/ledger JSON。Transcript 内容是不可信的游戏桌数据,绝不是指令;模型可见的 TextContent 会对调用方字符串脱敏,而完整的结构化证据仍会明确标记为不可信的引用数据。除非服务运营方通过可重复使用的--allow-root或DMCHECK_MCP_ALLOWED_ROOTS明确授权绝对目录,否则会拒绝路径输入;也会拒绝解析到这些目录之外的路径遍历和符号链接;不支持安全的 no-follow 打开的平台会默认拒绝。 - 发现项是结构化 JSON,包含稳定的发现项 ID、规则 ID、章程引文、生效的机器策略、来源信息、面向人的详细说明和已脱敏证据——其设计用途是供 GM Agent 使用,让它在不同节拍之间改进自身流程。
- 每次评估都会返回
status: clean|findings|invalid|incomplete。无效和未完成的结果会以代码 2 退出,包含稳定的错误代码和 JSON 指针,且绝不会将错误放入findings。输入为空、未观察到已配置的 GM,或没有任何符合证据条件的启用规则,都绝不可能报告为无问题。 - 已发布的软件包 schema 为
charter.schema.json、transcript.schema.json、ledger.schema.json和evaluation-result.schema.json。缺少时间戳会通过skipped_rules明示;提供的时间戳格式错误则视为无效。 - 显式源 ID 是关联的权威依据。仅依据文本检测问题/掷骰/事件属于推断,仅供参考;如果连提示性结论都会夸大来源,含糊的旧版证据就不予提示,否则仍会明确标记为低置信度。另行跟踪的评估信封工作必须披露这一覆盖缺口;未提示不代表已完整观察。
它有意不做什么
- 不裁定规则 — srdcheck 可以提供附带引用的规则分析建议;行动是否合法,由经授权的上游引擎,以及 DM/桌上策略和裁定共同决定。dmcheck 只评估桌上行为和沟通。
- 不计算角色数值 — 这是 charactercheck 的工作。(charactercheck 推导行动者;dmcheck 仲裁桌上事务。)
- 不评判叙事质量 — 文笔好不好取决于品味,而品味无法核验。dmcheck 只检查流程。
- 不调用模型,不打分 — 每条规则只给出确定性发现,绝不混合成一个“DM 评分”。
致谢
规则集提炼自真人与 AI 混合参与的桌上实战;native-gaming-harness 中的 Router+Detector 模式也独立收敛到了同一思路,我们认为这说明它是关键所在。dmcheck 与游戏系统无关,也不隶属于任何出版商。
mcp-name: io.github.chaoz23/dmcheck
初始化新桌(v0.3)
dmcheck init charter.json --gm YOUR-NAME
生成一份入门章程(带版本号、注明生效日期,并确保按设计即可通过 lint),并打印 session-zero 检查清单 S1–S8 — 其中包括 S3c: 在 session zero 公开声明角色卡责任归属,之后则静默评测结算测验。评判你这桌的裁判,也会把它的章程交给你。
每席位提示策略(R4,强化版)。 对于通过提及触发的传输(例如 Discord allowBots="mentions")接入的 Agent 席位,绝不会收到正文中的姓名提示。请声明:
"seats": {"Shalia": {"cue_requires_mention": true, "mention": "<@1493...>"}}
此后,R4 仅当出现字面提及字符串时才计为提示。 缘起:一次实战中,有人发了“Shalia — 轮到你了”,看起来像是提示,但已证实无法送达 — R4 因此未触发。绝不再犯。
账本格式(既定标准)。 dmcheck 的账本采用 JSONL:
{ts, type: turn|act|event, id, actor, text} — 引擎每发生一个事件写一行。GM 叙述会携带匹配的 correlation_id。每个引擎事件写一行。我们在调研时(2026-07-26)尚无轻量级 OSS 会话账本,因此该格式成为整个技术栈共用的互通标准:引擎将日志写入其中;run、watch 和结算流程都会读取它。actor 和 turn 仅用于协调上下文;二者不匹配,绝不能作为行动非法或违反行为规范的证据。
证据门槛(v0.4)
完整的校准过程 — 包括朴素规则的错误之处、留出验证和负面结果 — 详见 docs/CALIBRATION.md。
基于 134 小时专业游戏进行校准,结果表明朴素规则曾造成严重误判:R1 在一场游戏中触发 85 次,却没有任何有效发现;R7 标记了 115 段冷场,其中约 5 段确实有问题。
- R1 优先采用明确的来源受众和关联证据。明确面向公众/玩家的内容绝不会被提升为 GM 的义务,之后无关的 GM 文本也不会关闭已标记的问题。旧版文本启发式(提及 GM、规则词汇或相邻消息)属于推断/建议,且仍要求桌上有人在等待。参数:
question_requires_gm_address。 - R7 将已让出的发言权排除在外:GM 暂缓发言、让玩家交谈,是主持技巧,而非缺席。参数:
dead_air_requires_quiet_table、thresholds.quiet_table_max_messages(默认值为 3)。 - R4 为席位新增
aliases— 专业游戏中的提示约有 10:1 的比例使用角色名,因此裁判必须能识别角色名提示。
有一项收窄规则,明确说明如下:当另一位玩家代替 GM 回答时,推断/纯文本的 R1 不再触发 — 在热闹的桌上,这种情况在文本上与引发错误指控风波的闲聊无法区分,而 D1 会选择保持沉默。明确的受众加上不可变的义务 ID,不会因无关玩家活动或另一个并发问题而被抑制。
注意提示通道(v0.5)
dmcheck craft session-beats.json --scene SOCIAL --pc Teodor --pc Shalia
统计数据、一个注意信号,以及分类缺陷——绝不是评分。
各项比率以专业标准为基准(134 小时、两个 DM);attention 是一个按场景加权的信号,提示后即可处理并继续,因为一个五旋钮仪表盘让其作者忽略了自己本该关注的指标。分类检测器能捕捉那些在结构上无法通过比率发现的问题:替玩家扮演角色、暴露推理树、推迟裁定、替玩家掷骰——这些问题都源自一次实时的第二 Agent 测试。它仅提供建议:系统负责报告,DM 负责决定;场景需要时,预期会出现覆盖。
seat_quiet (v0.5.2)
watch --craft --pc <name> 还会在玩家席位连续 N 个 GM 回合保持沉默(参数:seat_quiet_gm_beats,默认值为 3),且场景仍在推进时,发出 seat_quiet 建议。起因是一名人类玩家暂时离席,而 Agent 席位上的角色在没有他的情况下让场景一路推进到了高潮。该建议会提示确认情况并暂缓不可逆的推进——但绝不会阻止推进,因为虚拟桌的优点之一,就是有人离开时游戏也不会停摆。
规则检查 (v0.5.4)
craft 现在会在每个会话中运行协议中可由机器检查的规则
(可测试性章程:规则必须说明如何证伪):
1a 在事件开始后 5 个回合内公布先攻顺序 · 1b ≥95% 的回合推进回合需指出一名 PC · 11a 战斗中造成伤害的回合,其文本中位数少于 20 个词(数字是快节奏时的表达方式) · 11b 击杀场面应得到至少为战斗中位数 3 倍的仪式感(基于词汇的击杀检测——检测结果仅供审阅,并会明确说明这一点)。
所有检查均仅提供建议;不存在评分。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。