najamjad-cop
Pursuit League - 警察智能体 👮
这是《AI 智能体编排》课程两人期末项目中警察/警方一侧的代码: 一个分布式警匪游戏,通过 MCP(FastMCP/HTTP)与其他团队的智能体点对点对战, 具备 SHA-256 承诺-揭示完整性,并通过 Gmail API 上报结果。
配套仓库(小偷智能体): https://github.com/najikay/pursuit-thief-agent 两个仓库共用的核心包逐字节完全相同,由 CI 中的
scripts/sync_core.py强制保证(见docs/PLAN.md、ADR-002)。
团队: Naji Kayal · Amjad Abed
状态: M6 - 已对六个不同对手完成并提交六个计分系列,
规则 31 的通过阈值已三次达标。可完整运行一套经过审计的系列赛,能与
课程参考模拟器及六个独立团队实现互操作,并在赛后审计对手的对局。
剩余工作记录在 docs/TODO.md 中。
联赛战绩
# | 日期 | 对手 | 结果 | 我方 | 对方 |
1 | 2026-08-08 |
| 胜 6–0 | 90 | 30 |
2 | 2026-08-13 |
| 胜 6–0 | 90 | 30 |
3 | 2026-08-14 |
| 负 0–6 | 30 | 90 |
4 | 2026-08-17 |
| 胜 4–2 | 60 | 40 |
5 | 2026-08-18 |
| 负 0–6 | 30 | 90 |
6 | 2026-08-21 |
| 平 3–3 | 75 | 75 |
六套计分系列共三十六个小局,在审计中全部核验为 Verified OK,且没有一场技术性失利归因于我方。 这是我们最想先指出的数字:我方参加的每一场比赛,双方都能重新计算哈希并达成一致,包括我们惨败的那两场。
有两个系列与对手自己提交的报告逐字段核对一致——vibecode 的系列在 66 个字段上零差异,以及之后一场对阵 anrbj666 的友谊赛,六个子局全部匹配,两个 mutual_agreement.sha256 值也一致,每个窗口的 github_commit 对都吻合。只有与对手报告一致的结果,才是在规则 33-35 下不可能被作废的报告,而它对我们来说比一个比分更有价值。
目录
Related MCP server: Police MCP Server
安装
环境要求
Python | 3.12+(由 uv 管理——你无需预先安装) |
这里使用的唯一包管理器(指南 §8.4) | |
操作系统 | Linux、macOS 或 Windows 上的 WSL2——在 WSL2 上开发 |
可选 | 用于公网隧道的 |
git clone https://github.com/najikay/pursuit-cop-agent.git
cd pursuit-cop-agent
uv sync # installs the locked dependency set
uv run python scripts/check_all.py # every CI gate, one PASS/FAIL verdictcheck_all.py 通过即表示安装完好:包括 lint、文件大小限制、仓库
规则、类型检查和完整测试套件。
密钥 - 将 .env-example 复制为 .env 并填入真实值。任何机密都不会被
提交;.gitignore 涵盖 .env、secrets/、token.json 和 credentials.json,如果
有任何一个被跟踪,CI 门禁会使构建失败(教材规则 39-40)。
cp .env-example .env # then edit: ANTHROPIC_API_KEY, DEEPSEEK_API_KEY, …故障排查
症状 | 原因和修复 |
| 另一个智能体正在运行。停止它,或修改 |
| 正常现象:正在导入 MCP 技术栈。真正就绪时会打印 |
对手报告我方不可达 | 检查隧道: |
| 请从仓库根目录运行;控制台脚本位于本仓库的 |
OAuth 浏览器不弹出(WSL) | 这是预期行为——WSL 没有默认浏览器。使用 |
在 | Windows 挂载的文件系统在 WSL 中很慢。事件日志保持其句柄打开正是出于这个原因;如果可能,请将工作区放在 Linux 文件系统上。 |
命令行
每个仓库一个控制台脚本(这里是 najamjad-cop,配套仓库中是 najamjad-thief)。每个
动词都只是参数解析加上一次 SDK 调用——CLI 不含任何游戏逻辑,并且有一个
元测试来保证这一点。
uv run najamjad-cop --help # every verb
uv run najamjad-cop version # code version (book rule 53)
uv run najamjad-cop preflight # match-day checklist
uv run najamjad-cop peer # serve: MCP server + tunnel + dashboard
uv run najamjad-cop match # serve, then play the agreed series
uv run najamjad-cop peer --no-tunnel --no-dashboard # local play, nothing exposed
# Re-hash every step of a log and print the verdict. Paths are literal -
# `<log>` would be read by the shell as a redirect, so use a real one:
uv run najamjad-cop replay tests/goldens/artifacts/log_segal-police-team-vs-segal-thief-team_g01.json
uv run najamjad-cop replay path/to/log.json --serve # open the viewer instead
uv run najamjad-cop archive match.zip # bundle evidence (secrets excluded)退出码,因为这些命令会在脚本中运行:
代码 | 含义 | 示例 |
| 执行成功 | preflight 就绪,日志已核验 |
| 执行了,但结果不好 | 未达到比赛就绪状态,日志被篡改 |
| 无法执行 | 日志文件缺失或不可读 |
被篡改的日志和缺失的文件故意使用不同的退出码:审计结果绝不能 被误认为是拼写错误。
开发命令
uv run python scripts/check_all.py # all CI gates, one verdict
uv run python scripts/self_play.py --games 100 # measure our brains vs baselines
uv run python scripts/demo_dashboard.py # dashboard over a played game
uv run python scripts/two_process_match.py # both repos as real processes
uv run python scripts/sync_core.py ../pursuit-thief-agent # verify the mirrored core运行方式
以下所有内容都可以从一个全新的克隆开始运行,无需对手、无需 API 密钥。 智能体仅凭模板即可完整运行一套经过审计的系列赛(教材第 67 页)——LLM 是增强功能,而非依赖项。
1. 安装并验证安装
git clone https://github.com/najikay/pursuit-cop-agent.git
cd pursuit-cop-agent
uv sync # locked dependency set
uv run python scripts/check_all.py # every CI gate, one verdictALL GATES PASSED 表示 lint、文件大小、仓库规则、类型、策略
套件和 1,900+ 个测试全部通过。
2. 作为对等节点提供服务,并开启仪表盘
uv run najamjad-cop peer --dashboard --no-tunnel等待 Uvicorn running——这才是就绪信号,而不是第一行日志。冷
启动约需 15 秒(导入 MCP 技术栈),所以比赛日要提前启动。
然后打开 http://127.0.0.1:8000/。
端口和主机来自 config/setup.json(ui.port、ui.host)。它按设计绑定到
回环地址:仪表盘显示的是我方的信念和我方密封的状态,
暴露它等于把承诺-揭示机制要隐藏的一切都交给对手
(规则 8-9)。
你能看到什么:
面板 | 展示内容 |
Board | 对数刻度上的信念热力图——线性刻度曾把 48 个格子中的 47 个压成一个色带 |
Turn banner | 谁的回合、哪一步、哪个阶段 |
Dialogue | 进出的每一条提示,以及写出它的模型 |
Negotiation | 提议 → 反提议 → 锁定,以及等待人工处理的条款 |
Budget | 相对于约定的 200k 上限的令牌消耗 |
Match day | 就绪状态——与 |
Testing | 练习模式,以及每个端点是否在应答 |
Matches | 我方已提交的每场比赛:比分、每局审计结论、产物 |
Events | 原始事件流 |
更新通过 WebSocket 推送;客户端从不轮询。仪表盘故障 不可能影响对局——它只是一个订阅者,仅此而已(ADR-005)。
可选控制。 在 config/setup.json 中将 features.controls 设为 true
即可从页面启用开始/停止、谈判审批和练习模式开关。默认关闭,
而且刻意没有任何按钮可以触发一场计分比赛——那是需要评分且不可撤销的,
docs/RUNBOOK.md 才是操作它的界面。
2b. 不打扰讲师即可测试
Testing 面板回答了另外两个通常需要翻日志才能弄清的问题。
我处于哪种模式? 练习模式会把每份报告重定向到你自己的收件箱,而不是
讲师的收件箱,并在主题前加上 [PRACTICE] 前缀。它不会跳过
发送这一步——发送正是作业 6 中导致失分的环节,所以一次练习运行会
真实地执行发送,你会读到实际的邮件。重定向被强制执行两次:地址先被重写,
然后在不可反悔的发送点再次检查,因此一个静默失败的重写会抛出错误,而不是
把邮件发出去。见 docs/CONFIG.md §3b。
最简单的是那个命令行标志——它只为一次进程启用练习模式,不触碰任何其他东西:
uv run najamjad-cop match --opponent amjad --practice --dashboard --tunnel或者从面板切换(需要开启 features.controls),或者把
config/setup.json 中的 practice.enabled 设为 true 使其持久生效。每次构建
报告时都会重新读取该设置,所以开关无需重启即可生效,并且它会覆盖
email.mode 为 send——一次悄悄生成草稿的练习运行看起来
会和一次成功的发送完全一样。
真的有人可达吗? Probe endpoints 会拨叫我们自己的 MCP URL 和 对手的 URL,并报告三种状态,而不是两种:
状态 | 含义 |
绿色 | 有东西在该地址接受了 TCP 连接 |
红色 | 已配置,但没有任何程序在监听——这会阻止一场比赛 |
灰色 | 尚未配置——只是没有安排比赛,不是故障 |
绿灯表示端口有响应。它不表示协议可用, 也不表示对方会同意我们的条款——那是握手阶段要做的事, 这个面板刻意只声称它能检查到的内容。
3. 检查你是否已准备好比赛
uv run najamjad-cop preflight # exit 0 or do not play
uv run python scripts/pre_match_smoke.py # MATCH READY in ~50 s4. 开始比赛
先写一张对手卡片,然后按名字引用它。opponents/<name>.toml 携带
两个来自对方的事实:它们的 MCP 端点,以及它们握手时声明的 group_id:
url = "https://their-agent.example.com/mcp"
group_id = "their-group"
name = "Their Team"
notes = "quick tunnel - URL changes if cloudflared restarts"从复制 opponents/_template.toml 开始。之后每个动词都接受 --opponent:
uv run najamjad-cop preflight --opponent amjad
uv run najamjad-cop match --opponent amjad --dashboard --no-tunnel无需编辑任何被跟踪的文件,上一个对手的设置不会被
下一个覆盖,而且 opponent_group_id——它必须等于对方
握手时声明的值,否则报告会用占位符而不是对方的名字
作为键——可以提前一天审查,而不是在握手时才临时发现。
一张卡片只能设置 network.opponent_*。游戏条款在已签名的
config/game.json 中达成一致,而对其中一项的按对手覆盖,恰恰是绝不能让之变得容易的事情。
或者手动在 config/police/game.toml 中设置 network.opponent_url,然后:
uv run najamjad-cop match --dashboard --no-tunnel一场完成的比赛会按照附录 F 将四份工件写入
workspace/artifacts/——声明、配置、日志和结果——并通过电子邮件发送结果。用以下命令检查它们:
uv run python scripts/post_match.py --opponent <name>5. 在没有对手的情况下尝试
两种方式,都是真实的:
# our cop against our thief, two OS processes over real MCP/HTTP
uv run python scripts/two_process_match.py
# against the course reference simulator (expects ../reference-sim)
uv run python scripts/rehearsal.py --games 6第二种才是关键——它是唯一曾捕获我们互操作缺陷的设置,因为它是唯一一个不是我们编写的对手。
6. 验证日志
uv run najamjad-cop replay workspace/artifacts/log_<game_id>_g01.json退出码 0 表示 Verified OK;退出码 1 表示 TAMPERED 并指出失败的步骤;
退出码 2 表示文件无法读取。被篡改的日志与拼错的路径被刻意赋予不同的代码——审计裁决绝不能被误认为输错了路径。
加上 --serve 可打开查看器,而不是打印裁决。
7. 测量
uv run python scripts/strategy_smoke.py --games 50 # win rates with intervals
uv run python scripts/sweep.py --games 24 # parameter sensitivity
uv run python scripts/measure_tokens.py # token census结果存放在 results/ 中,notebooks/analysis.ipynb 绘制的正是这些结果。
比赛日工作流程
包含确切命令的完整流程见 docs/RUNBOOK.md。概览如下:
热身 - 尽早启动智能体;冷启动约 ~15 秒。
预检 - 运行
uv run najamjad-cop preflight;退出码为 0,否则不进行比赛。交换 URL - 在
config/police/game.toml中设置network.opponent_url。比赛 - 运行
uv run najamjad-cop match,仪表板在 http://127.0.0.1:8000/。审计 - 每个小局自动进行;每局都必须验证为
Verified OK。报告 - 与对手对账,然后发送(规则 30:仅使用
gmail.send)。归档 - 运行
uv run najamjad-cop archive match.zip(不含机密)。
配置
文件 | 作用 |
| 共享的、已签名的条款。 双方对等节点必须持有逐字节相同的副本;握手过程在任何不匹配时都会拒绝比赛。我们的是开局提案——每个值都达到或高于附录 F 的最低要求(规则 12:只升不降)。 |
| 私有、本地。 我们的端口、对手 URL、隧道主机名、LLM 选择、信念调参。绝不跨越网络。 |
| 按服务划分的限流器设置,加载时对照附录 F 的上限进行校验。 |
| 仅存放机密。绝不提交。 |
值得了解的参数:
键 | 作用 |
| 我们的 MCP 端口(警察 8802 / 窃贼 8801,这样两者都可在本地运行)。 |
| 我们对对手唯一知道的信息。为空时预检失败。 |
| 永久的公开名称。一个具名隧道会在重启后保留其 URL——这正是让作业 6 花费最多时间的缺陷(ADR-004)。 |
| 提示节奏。它是质量旋钮,而不是省钱旋钮——参见 |
| 面对可能说谎的提示时,我们对气味的信任程度。 |
| 已商定的规则。单方面更改会破坏签名。 |
仪表板
使用 --dashboard 启动它并打开 http://127.0.0.1:8000/——关于面板和可选控件,参见 运行它 §2。
信念热力图、回合横幅、带有逐条消息模型来源的对话、谈判时间线、令牌预算和报告投递状态——通过 WebSocket 推送,从不轮询。它只显示局部真相(规则书规则 8-9):对手的位置在读模型中没有字段,并且一个元测试强制要求 UI 只能通过 SDK 访问智能体。

回放查看器
每一步都根据其已揭示的 (payload, nonce) 重新计算哈希,并与存储的承诺进行比较(规则书规则 20)。下面,讲师自己的示例日志干净地回放:

以及同一份日志在事后编辑了一条记录后的情况——伪造被精确定位到其植入的那一步,规则 19 使该局无效:

关于每张图片是如何复现的,参见 assets/README.md。
学术报告
模型:双方都无法看见的 Dec-POMDP
该游戏是一个去中心化、部分可观测的马尔可夫决策过程。两个智能体都无法观测真实状态:位置被密封在承诺中,直到终局审计才揭开,因此每个对等方都会对其他方可能所在的位置持有信念,并据此行动。
两个观测通道,具有相反的信任属性:
气味 - 对手不由自主散发、无法伪造的衰减信息素痕迹(规则书第 22 页)。无法伪造,但模糊不清。
两种模型随附,每场比赛可以选择其中任意一种。 规则书(第 43-44 页)是径向的——0.90 / 0.62 / 0.42 / 0.20 / 0.14 / 0.04——采用相对衰减
τ ← (1-ρ)·τ;参考模拟器则按切比雪夫距离线性衰减——环值 0.90 / 0.60 / 0.30——采用绝对衰减τ ← τ - ρ。我们实现了这两种,并且两者都已注册到互操作套件中:ScentModel.BOOK是multiplicative_book_v1(934c220d…),ScentModel.REFERENCE是subtractive_chebyshev_v1(81ebee59…)。每种都复现了套件自身发布的向量——包括线上的发送顺序,套件的field_walk将其固定为使先前的痕迹老化,将新鲜沉积物以未衰减状态合并,然后发送该结果:在 2026-08-22 之前,我们的窃贼发送的痕迹始终新鲜了一个衰减步,一个对手的逐帧检查测量到了这一点,现在这些帧已与 walk 逐格对照钉死(test_wire_scent_serve_order.py)。因此,匹配一个对手只需一个键——config/game.json中的pheromones.pheromone_model——而不是对十四项已签名条款的更改,这样契约摘要a284082d…在切换后依然有效,没有人需要重新签名。我们在协商时声明的摘要是从所配置的模型中查得的,因此不存在我们发出一种物理规则、却声称另一种的状态。信息素发射与提示分开调节——--scent full|window|none和--hints/--no-hints——因此完全静默的系列只需一个标志;在静默状态下我们不声明任何模型,因为对一个没有人发送的字段所做的声明,根本不值得声明。提示 - 自由形式的自然语言,规则明确允许其说谎(规则 26-27)。精确但不可信。
我们的信念引擎融合了它们:用扩散处理移动,用气味似然更新,以及每个对手的可信度权重——该权重随对手提示与痕迹相符或相悖而上下浮动。完整推导见 docs/PRD_belief_engine.md。
构建它时得到的三点发现,每一点都改变了设计:
气味衰减存在不动点。 保留三位小数的相对衰减永远不会达到零,因此已失效的痕迹会永远污染信念。用一个显式 epsilon 修复了这个问题。
乘法融合会重复计算累积的气味场,使信念落后移动中的对手 ~5 格。已被替换为稳健的混合更新。
平坦的似然会把信念停在痕迹中途。 锐化加上加性下限修复了这个问题;而钳制会让微弱气味与无气味无法区分。
编排困境
一个网关,还是多个调用方? 规则书第 3 条强制要求一个编排者,我们按字面意思执行:外围模块绝不互相调用。信念引擎对传输一无所知,策略对密码学一无所知,传输对规则一无所知。正是这一点使得整个回合循环可以用假对象来测试——这是作业 6 从未有过的接缝。
对假对象该信任多少。 这是我们最深刻的一课。三个不同的缺陷在 1500 个通过的测试中存活了下来,因为这些假对象比真实线路更宽容:一个假传输包装了真实传输没有包装的审计负载,一个从不阻塞的内存链路,以及一些只与自己交手的对等方。互操作只能针对不是你编写的东西来测试。
把截止时间放在哪里。 一个永远应答的对等方不能把我们困在一场已定胜负的比赛里,一个沉默不响应的对等方也不能变成我们的技术性失败。每一次等待都有上限,每一个结局都是被宣告的而非被假设的——见下。
对我们自己的协议做限流。 gatekeeper 的存在是为了对 Anthropic 和 Gmail 做一个好公民。把它应用到对手身上几乎让我们输掉比赛:我们自己的限流器可能会把回复延迟到超过他们 30 秒的截止时间。
策略,以及为何不用强化学习
警察 - 一种脚本化的对半封锁(strategy/seal_cop.py),不是逐回合评分:一边沿中列旁的通道行走,一边封锁中列,夺取闸门,切下窃贼所在的那一半,窃贼最终与我们同处一个 3×3 的小口袋。然后,domain/endgame.py 精确求解这个口袋——在它的博弈树中,放置障碍物也算一步——并把每一场胜利都定价为共处一格,因为“踩上”的声明是每一种实现都认可的捕获方式;被封锁在我们永远无法走到之处的窃贼,会被我们自己的基准计为 remote seal,并作为计划被拒绝。单障碍锁(strategy/lock.py:我们的身体加上一堵墙,需要相邻)可以提前终结被钉住的窃贼。基准测试(tests/regression/)让它与会反应的对手对抗——包括一个蹲在脚本自身墙线上的窃贼——而它能在 35 步之内,以普通可声明的捕获拿下全部对手(test_seal_converts_every_reacting_thief.py)。信念引导的追捕(cop_brain.py)仍然是针对无法定位的棋盘的后备方案。
窃贼 - 以生存为视野的规避是一套硬性下限,而不是贪婪的距离最大化:绝不在一个回合结束时处于警察一步之内,拒绝那些半成品围栏已让封锁变得廉价的格子,保留一个可达的 4×4,待在正在形成的切口的警察一侧(封锁者不得完成一堵将它与我们隔开的墙),并站在正在修建的围栏的缺口里——这个偏好晚于安全底线运行,因为先运行它曾一度把我们逼进对手随后封死的角落(test_ahk_yosi_corner_hunt.py 逐步回放了那条致命路线)。它能从 matches/ 中每一个存档的对手路线以及一个会反应的角落猎手警察的全部 24 种平局决胜变体中存活。
提示策略 - 虚张声势是一种有成本的战略资源:一条声明会暴露声明者的格子,因此一条虚假的捕获声明等于白白把我们的精确位置交给窃贼。
刻意不用强化学习:
整个联赛只有约 60 场真实对局可用——远不足以在如此大的状态空间上学习策略。
对手行为是非平稳的;每支队伍带来的东西都不同。
非确定性会破坏回放,而回放是一项计入成绩的交付物。
启发式方法已经决定性地击败了基线(见下文),因此强化学习只会带来没有可衡量收益的风险。
相反,我们采用在线对手建模,其规模与一个系列实际提供的约 210 个观测值相匹配——提示可信度、移动倾向、屏障响应。
衡量方式是通过真实的比赛机制在留出对局上进行——种子 11,调参时从未使用,每个对阵 60 场:
对阵 | 捕获次数 | 比率 | 95% Wilson 置信区间 |
我们的警察 vs 贪婪小偷 | 60/60 | 100 % | 94–100 % |
贪婪警察 vs 我们的小偷 | 0/60 | 0 %(100 % 存活) | 0–6 % |
贪婪 vs 贪婪(参考) | 4/60 | 6.7 % | 2.6–16 % |
全部 180 场对局中,对等方分歧为零,审计失败为零。

一个可调参数决定比赛胜负,而且不是我们预想的那一个:

barrier_threshold 在整个取值范围内将捕获率从 4 % 到 100 % 摆动。屏障对双方都是不可逾越的,因此一个基于薄弱证据筑墙的警察会把自己隔离在它所追捕的小偷之外——我们曾连续数周把 0.15 发布上线,这让我们损失了大约三分之一的对局。lookahead 是一个真正的零结果:深度 1–4 产生字节一致的对局,因为各向同性扩散核保持了它本应区分的候选移动的排序。
我们有义务说明的告诫。 我们的小偷能熬过我们遇到过或存档过的每一个警察——却仍然会在大约第 30 步时输给我们自己的封堵者,后者的减半计划没有任何对手展示过。两个方向都被明确记录,而不是被掩盖(test_thief_beats_sealing_cops.py 记录了这次失败及其代价;角落搜索和存档测试套件记录了存活情况),因为一个只针对它能击败的警察来进行评估的小偷,实际上是在对自己进行评估。
完整的推导、置信区间、token 成本表和参考文献都在 notebooks/analysis.ipynb 中。复现方式如下:
uv run python scripts/baselines.py --games 60 --seed 11 # held-out comparison
uv run python scripts/sweep.py --games 24 --seed 7 # sensitivity sweeps
uv run python scripts/measure_tokens.py # token census与陌生对手测试给我们的教训
我们克隆了课程参考模拟器,并让它来与我们对接。两个方向都行不通。 参考实现把 MCP 工具参数命名为 message(三个工具)和 payload(一个工具);我们向全部四个工具都发送了 payload,并且只接受 payload。每一轮和每一个提议都在任何游戏逻辑运行之前就被参数绑定拒绝了——对于任何基于参考实现构建的智能体都是如此,而班上大多数智能体都是这样构建的。
接着又出现了四个不兼容点:一个我们从未发送过的必填 timestamp,一个他们的解析器直接拒绝的 claimed_cell 字段,以及三个类型不同的声明字段。然后,审计揭示结果实际上是以裸列表形式发送的,而模式声明的是信封结构,因此双方在没人作弊的对局中都记录了 TAMPERED。
每一个这样的问题都通过了我们自己的测试。相比之下,提交-揭示核心经受住了实际对接,原样未变:我们的 commit_of 逐字节复现了参考实现的签名。
我们要带到任何分布式项目中的教训是:一套全绿的测试套件证明你的代码与你的假设一致,而不是证明你的假设是对的。
文档
文档 | 用途 |
| 产品需求(FR-* 标识、KPI、里程碑) |
| 架构:C4 + FSM 图、ADR-001..021、模块映射 |
| 688 项任务的构建计划,含可追溯性和进度 |
| 当前状态、未决事项,以及每一项经衡量的修正 |
| 什么会通过网络传输,什么永远不会 |
| 威胁模型、提示注入防御、秘密处理 |
| 尼尔森启发式原则映射到仪表板决策;无障碍设计 |
| 四个扩展接缝,附一个可运行的插件 |
| 每个配置键、其所在文件,以及其附录 F 可协商性 |
| 每个门禁检查什么,以及如何复现失败 |
| 约定:核心同步、提交、测试、比赛日冻结 |
| ISO/IEC 25010 质量特性映射到证据 |
| 每一个已处理的边界条件,各自链接到对应测试 |
| 实测 token 消耗与成本模型 |
| 已知不完整的内容,附证据 |
| 敏感性研究、基线、成本表、参考文献 |
| 机制设计 |
| 隧道与连接流程 |
| 来源摘要(规则书、指南、参考模拟器、A6 回顾) |
审计对手
提交-揭示证明对等方没有改写历史。但它并不能证明对方是否按规则行事,而这是两种不同的保证——我们在整个联赛阶段都把两者混为一谈,输掉一个系列后也无法说清那场比赛是否合法。
审计按设计是赛后进行的:规则 33-35 规定,相互矛盾的报告会使比赛无效,因此一个智能体如果基于自己的指控采取行动,就会把怀疑变成双方零分。下面所有内容都在记录证据,而不会改变我们的比赛方式(PLAN ADR-019)。
# replay their revealed records through the fair-play rules: movement legality,
# the Barrier Law, the budget, step order, hint length - and say what it could NOT check
uv run python scripts/audit_opponent.py --team vibecode
# are we disclosing scent on the same terms they are?
uv run python scripts/scent_parity.py --since 2026-08-14T16:00 # UTC
# 323 of 323 sealed capture claims name the claimer's own revealed cell
uv run python scripts/claim_evidence.py
# both repos must declare the same counted-match count (rules 37-38)
uv run python scripts/reconcile_counted.py ../pursuit-thief-agent --apply揭示能确定什么,以及只有线上数据才能确定什么:对等方的密封记录只包含该对等方选择密封的内容。移动和屏障仅凭存档即可检查;smell_grid、capture_claim、hint 和响应时间只能对照线上实际到达的数据进行检查,这正是 FrameLog 按发送原样保存它们的原因。审计报告将这些问题标记为不可检查,而不是把它们并入一个干净的结论——“我们检查过并达成一致”和“没有可检查的内容”绝不能读起来一样。
约束所有策略的三个结果
所有这些都是联赛阶段通过测量确立的,并且都具有决定性意义。
一个警察无法在空旷棋盘上逼近并抓住小偷。 7×7 网格是两条路径的笛卡尔积,因此其警察数为 2(Maamoun & Meyniel 1987),对全部 49×49 个状态进行穷举不动点计算发现,在同时移动的规则下,没有任何状态能让一个仅靠移动的警察强制捕获。我们的警察将小偷追到距离 2 并保持 28 步,这是一个定理,而不是缺陷。屏障是唯一能改变这个答案的资源(PLAN ADR-021)。
而有了计划,屏障确实能改变答案。 减半封堵可以破解测试台能构建的每一个被动反应型小偷——棋盘减半,一半再减半,3×3 精确求解,最终在 35 步内以同格声明结束。上述两个约束仍然主导着这场胜利的形态:它必须以小偷确认的声明结束,而且不能仅靠移动实现。这里长期记录为我们最大竞争风险的东西——一个追踪到距离 2 并保持的警察——已经闭合;剩下的风险是,对手自己的警察也能打出与我们一样完整的计划,而我们小偷的下限正是针对这种情况来定价的。
tests/regression/cop_duel.py 是用于验证这些断言的警察侧基准——我们的警察对战一个自适应小偷,并使用真实入口路径根据气味构建出的信念。录制的对手线路不会反应,因此无法衡量逼近效果。
许可证与署名
MIT(见 LICENSE)。协议形态和工件模式与课程参考模拟器 rmisegal/Game-P2P-Cop-Chase(教育许可证)互操作;当规则书与代码冲突时,以规则书为准。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Hosted MCP for Conductor Relay: a verifier-backed agent work exchange and cold marketplace.
Coordinate multiple AI agents over MCP: atomic claims, leases, shared ledger, handoffs, tasks.
Agent-native collaboration network: orchestrate a team of long-running agents from any MCP client.
Agent-native marketplace. Bootstrap, list inventory, search, negotiate, and trade via MCP.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables decentralized turn-based gameplay between thief and police agents in a peer-to-peer network, handling turn coordination, message passing, and protocol enforcement.
- FlicenseNot gradedqualityCmaintenanceEnables a police agent to autonomously chase a thief in a peer-to-peer grid game using FastMCP for turn-based communication and decentralized orchestration.
- FlicenseNot gradedqualityBmaintenanceImplements a distributed cops-and-robbers game agent as a FastMCP server, enabling peer-to-peer play with no central server. It manages turn-based moves, belief tracking, strategy selection, and secure protocol via SHA-256 commit-reveal.
- FlicenseNot gradedqualityBmaintenanceRuns a decentralized thief agent for a peer-to-peer cops-and-robbers game, using FastMCP to exchange moves and messages with a police agent while employing Bayesian belief and credibility-based bluffing strategies.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/najikay/pursuit-cop-agent'
If you have feedback or need assistance with the MCP directory API, please join our Discord server