Skip to main content
Glama
najikay

najamjad-cop

by najikay

Pursuit League - Cop Agent 👮

警察/警官側の、Orchestration of AI Agents の2人組最終プロジェクトです。 MCP(FastMCP/HTTP)を介して他のチームのエージェントとピアツーピアで対戦する分散型の泥棒と警官のゲームで、SHA-256 のコミット・リビール整合性と Gmail API による結果報告を備えています。

関連リポジトリ(泥棒エージェント): https://github.com/najikay/pursuit-thief-agent 共有コアパッケージは両リポジトリでバイト単位で同一であり、CI の scripts/sync_core.py によって強制されています(docs/PLAN.md、ADR-002 参照)。

ci

チーム: Naji Kayal · Amjad Abed ステータス: M6 - 6つの異なる対戦相手に対して、カウント対象のシリーズを6回プレイし、提出済み。ルール31の合格基準を3回満たしました。完全な監査付きシリーズをプレイし、コースの参照シミュレータおよび6つの独立したチーム実装と相互運用し、試合後に相手のプレイを監査します。残りの作業は docs/TODO.md に追跡されています。

リーグ戦績

#

日付

対戦相手

結果

私たち

相手

1

2026-08-08

uoh-ay26

勝利 6–0

90

30

2

2026-08-13

imreeyal

勝利 6–0

90

30

3

2026-08-14

vibecode

敗北 0–6

30

90

4

2026-08-17

MOAAMOHA

勝利 4–2

60

40

5

2026-08-18

nis-yar1

敗北 0–6

30

90

6

2026-08-21

ahk-yosi

引き分け 3–3

75

75

カウント対象の6シリーズ全体で、36/36のミニゲームが監査で Verified OK と確認され、私たちに起因する技術的敗北はゼロです。 それが私たちが最初に指摘する数字です。プレイしたすべてのゲームは、両者が再ハッシュして合意できるものであり、大敗した2試合も含まれます。

2つのシリーズは、相手が提出した報告書とフィールドごとに照合されました。vibecode のものは66フィールドで差分ゼロ、後の anrbj666 との親善試合では6つのサブゲームすべて、両方の mutual_agreement.sha256 値、および両方のウィンドウごとの github_commit ペアが一致しました。相手の報告書と一致する報告書だけが、ルール33〜35の下で無効にできない種類であり、それはスコアラインよりも私たちにとって価値があります。


目次


Related MCP server: Police MCP Server

インストール

要件

Python

3.12+(uv で管理 - 事前にインストールする必要はありません)

uv

ここで使用する唯一のパッケージマネージャー(ガイドライン §8.4)

OS

Linux、macOS、または WSL2 経由の Windows - WSL2 で開発

オプション

公開トンネル用の cloudflared、レポートメール用の Google Cloud プロジェクト

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 verdict

check_all.py が成功すれば、インストールは健全です。lint、ファイルサイズ制限、リポジトリルール、型チェック、完全なテストスイートが含まれます。

シークレット - .env-example.env にコピーし、実際の値を入力してください。秘密情報がコミットされることは決してありません。.gitignore.envsecrets/token.jsoncredentials.json をカバーし、CI ゲートは追跡された場合にビルドを失敗させます(ブックのルール39-40)。

cp .env-example .env          # then edit: ANTHROPIC_API_KEY, DEEPSEEK_API_KEY, …

トラブルシューティング

症状

原因と修正

port 8802 … already in use

別のエージェントが実行中です。停止するか、config/police/game.tomlnetwork.my_port を変更してください。

peer が約15秒かかる

正常です:MCP スタックのインポート中です。実際に準備ができたときに Uvicorn running と表示されます - 試合のずっと前に起動してください。

相手が私たちに到達できないと報告

トンネルを確認してください:uv run najamjad-cop preflight502 はエージェントが実行されていないことを意味します。JSON-RPC エラー("Client must accept text/event-stream" など)は、健全であることを意味します - それはブラウザが MCP エンドポイントにアクセスしているだけです。

Failed to spawn: najamjad-cop

リポジトリのルートから実行してください。コンソールスクリプトはこのリポジトリの .venv にあります。

OAuth ブラウザが開かない(WSL)

想定内です - WSL にはデフォルトのブラウザがありません。uv run python scripts/authorise_gmail.py --manual を使用し、URL を自分で貼り付けてください。

/mnt/c で全体的に遅い

Windows マウントのファイルシステムは WSL では遅いです。イベントログはまさにこの理由でハンドルを開いたままにします。可能であれば、ワークスペースを Linux ファイルシステムに置いてください。


コマンドライン

リポジトリごとに1つのコンソールスクリプト(ここでは 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)

終了コード(スクリプトで実行されるため):

コード

意味

0

成功

preflight 準備完了、ログ検証済み

1

実行されたが、答えが悪い

試合準備未完了、ログ TAMPERED

2

実行できなかった

ログファイルが存在しない、または読み取り不可

改ざんされたログと存在しないファイルは意図的に異なるコードです。監査結果がタイプミスと誤解されてはなりません。

開発コマンド

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 キーもなしで動作します。エージェントはテンプレートだけで完全な監査付きシリーズをプレイします(ブック PAGE 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 verdict

ALL 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.jsonui.portui.host)から取得されます。設計上ループバックにバインドされます。ダッシュボードは 私たちの 信念と 私たちの 封印状態を表示するため、公開するとコミット・リビールが隠すために存在するすべてを相手に渡すことになります(ルール8-9)。

表示内容:

パネル

表示内容

ボード

対数スケールの信念ヒートマップ - 線形では48セルのうち47セルが1つの帯に潰れました

ターンバナー

誰の手番か、どのステップか、どのフェーズか

ダイアログ

すべてのヒント(入出力)、それを書いたモデル付き

交渉

提案 → カウンター → ロック、および人間の承認待ちの条件

予算

合意された200kキャップに対するトークン

試合日

準備状況 - preflight が実行するのと同じチェック

テスト

練習モード、および各エンドポイントが応答しているかどうか

試合

提出したすべての試合: スコア、ゲームごとの監査判定、成果物

イベント

生のイベントストリーム

更新は WebSocket 経由で届きます。クライアントはポーリングしません。ダッシュボードの障害はゲームに影響しません - それは単なる購読者であり、それ以上ではありません(ADR-005)。

オプションのコントロール。 config/setup.jsonfeatures.controlstrue に設定すると、ページから開始/停止、交渉承認、練習モードの切り替えが有効になります。デフォルトではオフで、カウント対象の試合をプレイするボタンは意図的にありません - それは採点され、取り消し不可能であり、docs/RUNBOOK.md がそのインターフェースです。

2b. 講師に触れずにテストする

テスト パネルは、そうでなければログを掘り下げることを意味する2つの質問に答えます。

私はどのモードですか? 練習モードはすべてのレポートを講師の受信トレイではなく自分の受信トレイにリダイレクトし、件名に [PRACTICE] を付けます。送信をスキップしません - 送信は課題6で試合を失ったステップなので、練習実行は実際にそれを実行し、実際のメールを読むことができます。リダイレクトは2回強制されます。アドレスが書き換えられ、その後、戻り不能点でチェックされるため、静かに失敗した書き換えは配信する代わりに例外を発生させます。docs/CONFIG.md §3b を参照してください。

最も簡単なのはフラグです - 1つのプロセスに対して練習を有効にし、他には触れません:

uv run najamjad-cop match --opponent amjad --practice --dashboard --tunnel

または、パネルから切り替えるか(features.controls がオンの場合)、config/setup.jsonpractice.enabled を設定して永続化します。レポートが構築されるたびに新しく読み取られるため、再起動なしで切り替わり、email.modesend に上書きします - 静かに下書きを生成した練習実行は、成功した送信とまったく同じに見えるでしょう。

誰か実際に到達可能ですか? プローブエンドポイント は、私たちの MCP URL と相手の URL にダイヤルし、2つではなく3つの状態を報告します:

状態

意味

そこに 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 s

4. プレイする

相手カードを一度書き、それを指定します。opponents/<name>.toml彼らから 得られる2つの事実を保持します - 彼らの 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 - これは彼らのハンドシェイクが宣言するものと等しくなければならず、そうでなければレポートは彼らの名前ではなくプレースホルダーでキー付けされます - はハンドシェイクで発見されるのではなく、前日にレビュー可能です。

A card can only set network.opponent_*. Game terms are agreed in the signed config/game.json, and a per-opponent override of one is exactly the thing that must never be easy.

Or set network.opponent_url in config/police/game.toml by hand, then:

uv run najamjad-cop match --dashboard --no-tunnel

A finished match writes four artifacts per Appendix F into workspace/artifacts/ - declaration, config, log and result - and emails the result. Check them with:

uv run python scripts/post_match.py --opponent <name>

5. Try it without an opponent

Two ways, both real:

# 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

The second is the one that matters - it is the only setup that has ever caught our interop defects, because it is the only opponent we did not write.

6. Verify a log

uv run najamjad-cop replay workspace/artifacts/log_<game_id>_g01.json

Exit 0 is Verified OK; exit 1 is TAMPERED and names the failing step; exit 2 means the file could not be read. A tampered log and a typo are deliberately different codes - an audit verdict must never be mistaken for a mistyped path.

Add --serve to open the viewer instead of printing a verdict.

7. Measure

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 land in results/ and are what notebooks/analysis.ipynb plots.

Match-day workflow

The full procedure with exact commands is docs/RUNBOOK.md. In outline:

  1. Warm up - start the agent early; cold start is ~15 s.

  2. Preflight - uv run najamjad-cop preflight; exit 0 or do not play.

  3. Exchange URLs - set network.opponent_url in config/police/game.toml.

  4. Play - uv run najamjad-cop match, dashboard on http://127.0.0.1:8000/.

  5. Audit - automatic per mini-game; every game must read Verified OK.

  6. Report - reconcile with the opponent, then send (rule 30: gmail.send only).

  7. Archive - uv run najamjad-cop archive match.zip (secrets excluded).


Configuration

File

Role

config/game.json

Shared, signed terms. Both peers must hold a byte-identical copy; the handshake refuses to play on any mismatch. Ours is the opening proposal - every value at or above the Appendix F minimum (rule 12: raise, never lower).

config/police/game.toml

Private, local. Our port, opponent URL, tunnel hostname, LLM choices, belief tuning. Never crosses the network.

config/rate_limits.json

Per-service limiter settings, validated against the Appendix F ceilings at load.

.env

Secrets only. Never committed.

Parameters worth knowing:

Key

Effect

network.my_port

Our MCP port (8802 cop / 8801 thief, so both run locally).

network.opponent_url

The only thing we know about the opponent. Preflight fails while empty.

tunnel.hostname

Permanent public name. A named tunnel keeps its URL across restarts - the defect that cost Assignment 6 the most time (ADR-004).

llm.every_n_steps

Hint cadence. A quality dial, not a savings dial - see docs/TOKEN_BUDGET.md.

belief.smell_trust_weight

How far we trust scent against a possibly-lying hint.

movement_and_barriers.*

Agreed rules. Changing these unilaterally breaks the signature.


The dashboard

Start it with --dashboard and open http://127.0.0.1:8000/ - see Running it §2 for the panels and the optional controls.

Belief heatmap, turn banner, dialogue with per-message model provenance, the negotiation timeline, token budget, and report delivery status - pushed over a WebSocket, never polled. It shows local truth only (book rules 8-9): the opponent's position has no field in the read model, and a meta-test enforces that the UI can reach the agent only through the SDK.

Live dashboard

Replay viewer

Every step is re-hashed from its revealed (payload, nonce) and compared with the stored commitment (book rule 20). Below, the lecturer's own sample log replaying clean:

Verified OK

And the same log with one record edited after the fact - the forgery is localised to exactly the step it was planted in, and rule 19 voids the game:

Tampered

See assets/README.md for how each image is reproduced.


Academic report

The model: a Dec-POMDP neither side can see

The game is a decentralised, partially observable Markov decision process. Neither agent observes the true state: positions are sealed inside commitments until the end-of-game audit, so each peer holds a belief over where the other might be and acts on that.

Two observation channels, with opposite trust properties:

  • Scent - a decaying pheromone trail the opponent emits involuntarily and cannot fake (book PAGE 22). Unfakeable but blurry.

    Two models ship, and either can be selected per match. The book (PAGE 43-44) is radial - 0.90 / 0.62 / 0.42 / 0.20 / 0.14 / 0.04 - with relative decay τ ← (1-ρ)·τ; the reference simulator is linear in Chebyshev distance - rings 0.90 / 0.60 / 0.30 - with absolute decay τ ← τ - ρ. We implement both, and both are registered in the interop kit: ScentModel.BOOK is multiplicative_book_v1 (934c220d…) and ScentModel.REFERENCE is subtractive_chebyshev_v1 (81ebee59…). Each reproduces the kit's own published vectors - including the wire's serve order, which the kit's field_walk fixes as age the prior trail, merge the fresh deposit undecayed, transmit that: our thief shipped the trail one decay step too fresh until 2026-08-22, an opponent's per-frame gate measured it, and the frames are now pinned against the walk cell-for-cell (test_wire_scent_serve_order.py). So matching an opponent is one key - pheromones.pheromone_model in config/game.json - and not a change to the fourteen signed terms, so the contract digest a284082d… survives the switch and nobody has to re-sign. The digest we declare at negotiate is looked up from the configured model, so there is no state in which we emit one physics and claim another. Emission is separately dialled from hints - --scent full|window|none and --hints/--no-hints - so a fully silent series is one flag; under silence we declare no model at all, because a claim about a field nobody is sending is not a claim worth making.

  • Hints - free natural language, which the rules explicitly permit to be a lie (rules 26-27). Precise but untrustworthy.

Our belief engine fuses them: diffusion for movement, a scent-likelihood update, and a credibility weight per opponent that rises and falls as their hints agree or disagree with the trail. The full derivation is in docs/PRD_belief_engine.md.

Three findings from building it, each of which changed the design:

  • Scent decay had a fixed point. Relative decay rounded to three decimals never reached zero, so dead trails polluted belief forever. Fixed with an explicit epsilon.

  • **Multiplicative fusion double-count

  • リーグ全体で利用可能な実際のゲームは~60件のみ - このサイズの状態空間でポリシーを学習するには 到底足りません。

  • 対戦相手の挙動は非定常です。各チームが異なるものを出してきます。

  • 非決定性はリプレイを壊します。そしてリプレイは採点対象の成果物です。

  • ヒューリスティックはすでにベースラインを決定的に上回っているため(下記参照)、RLは測定された 利点のないリスクになります。

代わりに、シリーズが実際に提供する~210件の観測に合わせたオンライン対戦相手モデリングを 行います - 手がかりの信頼性、移動傾向、バリア反応。

測定は、実際のマッチ機構を通じてホールドアウトゲームで行いました - seed 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ゲームで、ピア間の不一致はゼロ、監査失敗もゼロでした。

貪欲なベースラインに対する我々の頭脳

1つのチューナブルがマッチを決めます。しかも、それは我々が予想していたものではありません:

どのつまみがゲームを左右するか

barrier_threshold は、そのレンジ全体で捕獲率を 4 % から 100 % に変動させます。 バリアは 両方 の側にとって通行不能なため、弱い証拠で壁を作る警察は、 追跡中の泥棒から自分自身を隔離してしまいます。我々は数週間 0.15 をリリースし、 それがゲームの約 3 分の 1 を犠牲にしました。lookahead は真のヌル結果です。 深さ 1 ~ 4 はバイト単位で同一のゲームを生成します。なぜなら、等方性拡散カーネルは、 分離するはずの候補手のランキングを保持するからです。

私たちが述べる義務を負っている注意点。 我々の泥棒は、これまで直面またはアーカイブしたすべての警察を生き延びます。 それでも、ステップ30前後で、我々自身のシーラーに負けます。 その半分にするプランは、どの対戦相手も示していません。両方向とも、なめらかにするのではなく固定されています (test_thief_beats_sealing_cops.py が敗北とその代償を記録し、 コーナーハントとアーカイブのスイートが生存を記録しています)。なぜなら、 自分が打ち負かす警察に対してだけ評価された泥棒は、自分自身に対して評価されたことになるからです。

完全な導出、信頼区間、トークンコスト表、および参考文献は 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 を3つのツールで、payload を 1つのツールで命名しています。我々は4つすべてに payload を送り、payload だけを受け入れました。すべてのターンとすべての 提案は、ゲームロジックが1バイトも実行される前に 引数バインドによって拒否されました。これは、参照実装に基づいて構築された あらゆるエージェント、つまりクラスの大半に対してです。

さらに4つの非互換が続きました: 必須の timestamp を我々は送信しておらず、claimed_cell フィールドは彼らのパーサーが完全に拒否し、型が異なる3つのクレームフィールドがありました。さらに、 監査リビールは、スキーマがエンベロープを宣言しているのに、裸のリストとして送信されることが判明し、 その結果、両ピアは、誰も不正をしていないゲームについて TAMPERED を記録しました。

これらのすべては、我々自身のテストを通過しました。対照的に、コミットリビールの中核は、接触後も 無傷で生き残りました: 我々の commit_of は参照実装のシグネチャをバイト単位で再現します。

あらゆる分散プロジェクトに持ち込むべき教訓: グリーンなテストスイートは、あなたのコードがあなたの 前提と一致することを証明するだけであって、あなたの前提が正しいことを証明するわけではありません。


ドキュメント

ドキュメント

目的

docs/PRD.md

製品要件(FR-* ID、KPI、マイルストーン)

docs/PLAN.md

アーキテクチャ: C4 + FSM 図、ADR-001..021、モジュールマップ

docs/TODO.md

トレーサビリティと進捗を備えた688タスクの構築計画

docs/HANDOFF-2026-08-14.md

現在の状態、未解決項目、測定されたすべての修正

docs/PROTOCOL.md

ワイヤーを越えるもの、決して越えないもの

docs/SECURITY.md

脅威モデル、プロンプトインジェクション対策、シークレットの取り扱い

docs/UX.md

ニールセンのヒューリスティックをダッシュボードの決定にマッピング; アクセシビリティ

docs/EXTENDING.md

4つの拡張シームと、動作するプラグイン

docs/CONFIG.md

すべての設定キー、そのファイル、および付録Fの交渉可能性

docs/CI.md

各ゲートがチェックする内容と失敗の再現方法

CONTRIBUTING.md

規約: コア同期、コミット、テスト、マッチデーのフリーズ

docs/ISO25010.md

ISO/IEC 25010 品質特性をエビデンスにマッピング

docs/edge-cases.md

処理されたすべての境界条件、それぞれがテストにリンク

docs/TOKEN_BUDGET.md

測定されたトークン消費量とコストモデル

docs/OPEN_ITEMS.md

不完全であることが判明しているものと、そのエビデンス

notebooks/analysis.ipynb

感度分析、ベースライン、コスト表、参考文献

docs/PRD_belief_engine.md · PRD_commit_reveal.md · PRD_llm_router.md

メカニズム設計

docs/runbook-network.md

トンネルと接続手順

docs/research/

ソースダイジェスト(書籍、ガイドライン、参照シミュレーター、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_gridcapture_claimhint、および応答時間は、ワイヤーに到着したものと照らしてのみ確認できます。 そのため FrameLog はそれらを送信されたまま保持します。監査はこれらを 確認不可 として報告し、 クリーンな判定に折り込むことはしません - 「我々は確認し合意した」と「確認すべきものは何もなかった」は 決して同じように読めてはならないからです。

すべての戦略を制約する3つの結果

これらはすべて、リーグフェーズ中の測定によって確立され、すべてが構造を支えています。

バリアは盤面を縮小できますが、泥棒を捕まえることはできません。 本には3つの捕獲 条件(ルール46-47)が与えられています。コースの参照実装は正確に1つだけ実装しています。その rules.py には thief_resultis_captured があり、バリア捕獲や不動化のチェックはどこにもありません。 我々が遭遇したすべての対戦相手は参照実装由来のため、封鎖は 我々 が得点し 彼ら が得点しないミニゲームを生み出します - これがルール33-35の矛盾です。すべての捕獲は、泥棒が確認するクレームでなければなりません (PLAN ADR-020)。

1人の警察は、開けた盤面では近づけません。 7×7 グリッドは2つの経路のデカルト積であるため、 その cop number(警察数)は2です(Maamoun & Meyniel 1987)。また、49×49 のすべての状態に対する 網羅的固定点計算では、同時移動の下で移動のみの警察が捕獲を強制できる状態は 存在しません。 我々の警察が泥棒を距離2まで追跡し、28ステップそこに留まるのは、欠陥ではなく定理です。 バリアだけが答えを変えるリソースです(PLAN ADR-021)。

そして、計画があれば、バリアはそれを変えます。 半分にするシールは、ベンチが構築できるすべての反応する泥棒を 変換します - 盤面を半分に、その半分をさらに半分に、3×3 を正確に解き、35手以内の同位置クレームで終わります。 上記の2つの制約は依然としてその勝利の を支配します: それは泥棒が確認するクレームで終わらなければならず、 移動だけでは得られません。長い間、我々の最大の競争リスクとしてここに記録されていたもの - 距離2まで追跡して 保持する警察 - は解消されました。残るリスクは、対戦相手自身の警察が 我々と同じくらい完全な計画を実行することであり、泥棒の下限はまさにそれに対して 価格設定されています。

tests/regression/cop_duel.py は、それらの主張をテストするための警察側ベンチマークです - 我々の 警察と適応型の泥棒との対戦で、実際の侵入経路が匂いから構築する信念を用います。記録された 対戦相手のラインは反応せず、接近を測定できません。


ライセンスと帰属

MIT(LICENSE 参照)。プロトコルの形状とアーティファクトのスキーマは、コースの 参照シミュレーター rmisegal/Game-P2P-Cop-Chase (教育用ライセンス)と相互運用します。本とコードが矛盾する場合、本が優先されます。

FastMCPFastAPIpydantic、および uv を使用して構築。

Maintenance

ActivityActive
ResponsivenessSyncing

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

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    Implements 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.
  • F
    license
    Not graded
    quality
    B
    maintenance
    Runs 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

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