Files
Gitea-Tools/tests/test_issue_978_instance_fleet_snapshot.py
T
sysadminandClaude Opus 4.8 0dbff6dcd5 fix(controller): production client_instance_id launch path and instance-aware mutation gate
Remediate review 655 blockers on PR #979 (issue #978):

B1 — Production launcher (mcp_application_launcher) mints one trusted
client_instance_id per application launch and propagates it to all five
namespace workers via GITEA_MCP_CLIENT_INSTANCE. launcher_entry and
multi_namespace_launcher_entries use that path. Workers never invent a
trusted ID; missing/malformed/user-supplied values fail closed.

B2 — _check_mcp_runtimes_diagnostics is instance-aware: two legitimate
instances sharing a profile are allowed when each has a distinct trusted
client_instance_id; duplicate workers for the same (instance, profile)
still fail closed. Worker identity/generation exported for peer scans.

Tests cover shared ID across five namespaces, distinct launches, multi-
instance same profile, same-instance duplicates, untrusted attribution,
and the production launcher path.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-30 10:12:16 -04:00

1435 lines
51 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Instance-level fleet identity and health snapshots (#978).
Covers the acceptance criteria for multi-instance fleets: two Codex launches
remain distinct, ten workers attribute correctly, same client_type is not a
duplicate, collisions fail closed, historical rows stay non-blocking, and the
controller/reconciler read surface grants no mutation authority.
All identifiers are synthetic.
"""
from __future__ import annotations
import inspect
import json
import os
import tempfile
import unittest
from datetime import datetime, timedelta, timezone
from typing import Any
from unittest import mock
import mcp_fleet_snapshot as fleet
import mcp_worker_identity as mwi
NOW = datetime(2026, 7, 30, 7, 0, 0, tzinfo=timezone.utc)
TTL = 900.0
NAMESPACES = ("author", "reviewer", "merger", "controller", "reconciler")
def _registry() -> mwi.WorkerRegistry:
handle, path = tempfile.mkstemp(suffix=".sqlite3")
os.close(handle)
os.unlink(path)
return mwi.WorkerRegistry(path)
def _alive(_pid: int | None) -> bool:
return True
def _dead(_pid: int | None) -> bool:
return False
def _register(
registry: mwi.WorkerRegistry,
*,
client: str,
instance: str,
session: str,
generation: str,
namespace: str,
pid: int,
now: datetime = NOW,
ttl: float = TTL,
fleet_run_id: str | None = "run-canary",
status_after: str | None = None,
worker_identity: str | None = None,
process_identity: str | None = None,
repository_binding: str = "/repo/Gitea-Tools",
startup_revision: str = "rev-live",
instance_id_provenance: str = fleet.INSTANCE_ID_PROVENANCE_TRUSTED,
role: str | None = None,
) -> dict[str, Any]:
identity = worker_identity or mwi.generate_worker_identity(
client, f"{session}-{namespace}", now=now, nonce=f"{pid}-{namespace}"
)
outcome = registry.register(
worker_identity=identity,
client_name=client,
client_instance_id=instance,
session_id=session,
generation_id=generation,
role=role or namespace,
profile=f"prgs-{namespace}",
namespace=namespace,
remote="prgs",
repository_binding=repository_binding,
pid=pid,
heartbeat_ttl_seconds=ttl,
now=now,
fleet_run_id=fleet_run_id,
process_identity=process_identity or f"pid-{pid}",
startup_revision=startup_revision,
loaded_revision=startup_revision,
parity_revision=startup_revision,
live_revision=startup_revision,
instance_id_provenance=instance_id_provenance,
pid_alive_probe=_alive,
)
outcome["identity"] = identity
if status_after and outcome.get("registered"):
if status_after == mwi.STATUS_RELEASED:
registry.release(worker_identity=identity, now=now)
elif status_after == mwi.STATUS_SUPERSEDED:
# Direct status write for historical rows.
with registry._tx() as conn: # noqa: SLF001 — test-only fixture
conn.execute(
"UPDATE worker_registrations SET status = ? WHERE worker_identity = ?",
(mwi.STATUS_SUPERSEDED, identity),
)
return outcome
def _five_workers(
registry: mwi.WorkerRegistry,
*,
client: str,
instance: str,
session_prefix: str,
gen_prefix: str,
pid_base: int,
now: datetime = NOW,
) -> list[dict[str, Any]]:
out = []
for i, ns in enumerate(NAMESPACES):
out.append(
_register(
registry,
client=client,
instance=instance,
session=f"{session_prefix}-{ns}",
generation=f"{gen_prefix}-{ns}",
namespace=ns,
pid=pid_base + i,
now=now,
)
)
return out
class InstanceIdentityTests(unittest.TestCase):
def test_generate_distinct_instance_ids(self):
a = fleet.generate_client_instance_id("codex", launch_nonce="a", now=NOW)
b = fleet.generate_client_instance_id("codex", launch_nonce="b", now=NOW)
self.assertNotEqual(a, b)
self.assertTrue(a.startswith("inst-codex-"))
self.assertTrue(fleet.assess_instance_identity(a)["trusted"])
def test_legacy_pid_fallback_not_trusted(self):
a = fleet.assess_instance_identity("pid-1234")
self.assertFalse(a["trusted"])
self.assertEqual(a["provenance"], fleet.INSTANCE_ID_PROVENANCE_LEGACY)
def test_missing_instance_id(self):
a = fleet.assess_instance_identity(None)
self.assertFalse(a["complete"])
self.assertEqual(a["provenance"], fleet.INSTANCE_ID_PROVENANCE_MISSING)
class TwoCodexInstancesTests(unittest.TestCase):
"""AC1AC3: two Codex instances, ten workers, same type not duplicate."""
def test_two_codex_instances_ten_workers(self):
registry = _registry()
inst_a = fleet.generate_client_instance_id("codex", launch_nonce="A", now=NOW)
inst_b = fleet.generate_client_instance_id("codex", launch_nonce="B", now=NOW)
_five_workers(
registry,
client="codex",
instance=inst_a,
session_prefix="sessA",
gen_prefix="genA",
pid_base=1000,
)
_five_workers(
registry,
client="codex",
instance=inst_b,
session_prefix="sessB",
gen_prefix="genB",
pid_base=2000,
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(status=None),
now=NOW + timedelta(seconds=10),
pid_alive_probe=_alive,
canonical_repository="/repo/Gitea-Tools",
expected_live_revision="rev-live",
)
self.assertEqual(snap["live_worker_count"], 10)
self.assertEqual(snap["instance_count"], 2)
self.assertIn("codex", snap["multi_instance_same_client_type"])
self.assertEqual(len(snap["multi_instance_same_client_type"]["codex"]), 2)
self.assertTrue(snap["same_client_type_not_duplicate"])
# No finding that treats same client_type alone as a duplicate.
for f in snap["active_blockers"]:
self.assertNotIn("client_type alone", f["detail"].lower())
by_inst = {i["client_instance_id"]: i for i in snap["instances"]}
self.assertEqual(by_inst[inst_a]["worker_count"], 5)
self.assertEqual(by_inst[inst_b]["worker_count"], 5)
self.assertEqual(set(by_inst[inst_a]["namespaces"]), set(NAMESPACES))
self.assertEqual(set(by_inst[inst_b]["namespaces"]), set(NAMESPACES))
self.assertTrue(snap["live_fleet_safe"])
def test_mixed_client_types(self):
registry = _registry()
_five_workers(
registry,
client="codex",
instance="inst-codex-1",
session_prefix="c",
gen_prefix="gc",
pid_base=10,
)
_five_workers(
registry,
client="claude_code",
instance="inst-claude-1",
session_prefix="l",
gen_prefix="gl",
pid_base=20,
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=5),
pid_alive_probe=_alive,
)
self.assertEqual(snap["instance_count"], 2)
self.assertTrue(snap["live_fleet_safe"])
class CollisionTests(unittest.TestCase):
def test_live_reuse_of_instance_id_different_client_types(self):
registry = _registry()
shared = "inst-shared-collision"
_register(
registry,
client="codex",
instance=shared,
session="s1",
generation="g1",
namespace="author",
pid=1,
)
# Second client type forced onto same instance id via direct SQL to
# bypass register's same-namespace guard and exercise classification.
with registry._tx() as conn: # noqa: SLF001
conn.execute(
"""
INSERT INTO worker_registrations (
worker_identity, client_name, client_instance_id, session_id,
generation_id, role, profile, namespace, remote,
repository_binding, pid, transport, token_fingerprint,
started_at, last_heartbeat_at, heartbeat_ttl_seconds,
fencing_epoch, status, process_identity, instance_id_provenance
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
""",
(
"claude_code-20260730T070000Z-aaaaaaaaaaaa",
"claude_code",
shared,
"s2",
"g2",
"author",
"prgs-author",
"reviewer",
"prgs",
"/repo/Gitea-Tools",
2,
None,
None,
mwi._ts(NOW), # noqa: SLF001
mwi._ts(NOW), # noqa: SLF001
TTL,
1,
mwi.STATUS_ACTIVE,
"pid-2",
fleet.INSTANCE_ID_PROVENANCE_TRUSTED,
),
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertIn(fleet.CLASS_INSTANCE_ID_COLLISION, classes)
self.assertFalse(snap["live_fleet_safe"])
def test_duplicate_namespace_within_instance(self):
registry = _registry()
inst = "inst-dup-ns"
first = _register(
registry,
client="codex",
instance=inst,
session="s-a",
generation="g-a",
namespace="author",
pid=11,
)
self.assertTrue(first["registered"], first)
# Direct second author under same instance (bypass register guard).
with registry._tx() as conn: # noqa: SLF001
conn.execute(
"""
INSERT INTO worker_registrations (
worker_identity, client_name, client_instance_id, session_id,
generation_id, role, profile, namespace, remote,
repository_binding, pid, transport, token_fingerprint,
started_at, last_heartbeat_at, heartbeat_ttl_seconds,
fencing_epoch, status, process_identity, instance_id_provenance
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
""",
(
"codex-20260730T070000Z-bbbbbbbbbbbb",
"codex",
inst,
"s-b",
"g-b",
"author",
"prgs-author",
"author",
"prgs",
"/repo/Gitea-Tools",
12,
None,
None,
mwi._ts(NOW), # noqa: SLF001
mwi._ts(NOW), # noqa: SLF001
TTL,
2,
mwi.STATUS_ACTIVE,
"pid-12",
fleet.INSTANCE_ID_PROVENANCE_TRUSTED,
),
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertIn(fleet.CLASS_DUPLICATE_NAMESPACE, classes)
def test_register_refuses_duplicate_namespace(self):
registry = _registry()
inst = "inst-reg-dup"
a = _register(
registry,
client="codex",
instance=inst,
session="s1",
generation="g1",
namespace="author",
pid=21,
)
self.assertTrue(a["registered"])
b = _register(
registry,
client="codex",
instance=inst,
session="s2",
generation="g2",
namespace="author",
pid=22,
)
self.assertFalse(b["registered"])
self.assertEqual(b.get("collision_kind"), "duplicate_namespace_worker")
def test_reused_worker_identity(self):
registry = _registry()
identity = mwi.generate_worker_identity("codex", "sess", now=NOW, nonce="fixed")
first = _register(
registry,
client="codex",
instance="inst-1",
session="s1",
generation="g1",
namespace="author",
pid=31,
worker_identity=identity,
)
self.assertTrue(first["registered"])
second = registry.register(
worker_identity=identity,
client_name="codex",
client_instance_id="inst-2",
session_id="s2",
generation_id="g2",
namespace="author",
pid=32,
now=NOW,
pid_alive_probe=_alive,
)
self.assertFalse(second["registered"])
self.assertTrue(second["collision"])
def test_reused_session_identity(self):
registry = _registry()
_register(
registry,
client="codex",
instance="inst-1",
session="shared-session",
generation="g1",
namespace="author",
pid=41,
)
_register(
registry,
client="codex",
instance="inst-2",
session="shared-session",
generation="g2",
namespace="reviewer",
pid=42,
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertIn(fleet.CLASS_SESSION_COLLISION, classes)
def test_reused_generation_across_instances(self):
registry = _registry()
_register(
registry,
client="codex",
instance="inst-1",
session="s1",
generation="gen-shared",
namespace="author",
pid=51,
)
_register(
registry,
client="codex",
instance="inst-2",
session="s2",
generation="gen-shared",
namespace="author",
pid=52,
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertIn(fleet.CLASS_GENERATION_COLLISION, classes)
def test_reused_pid_and_process_identity(self):
registry = _registry()
_register(
registry,
client="codex",
instance="inst-1",
session="s1",
generation="g1",
namespace="author",
pid=61,
process_identity="proc-same",
)
_register(
registry,
client="codex",
instance="inst-2",
session="s2",
generation="g2",
namespace="reviewer",
pid=61,
process_identity="proc-same",
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertIn(fleet.CLASS_PID_COLLISION, classes)
self.assertIn(fleet.CLASS_PROCESS_COLLISION, classes)
def test_ownership_fencing_collision(self):
registry = _registry()
_register(
registry,
client="codex",
instance="inst-1",
session="s1",
generation="gen-fence",
namespace="author",
pid=71,
)
# Second instance forced onto same generation+epoch via SQL.
with registry._tx() as conn: # noqa: SLF001
conn.execute(
"""
INSERT INTO worker_registrations (
worker_identity, client_name, client_instance_id, session_id,
generation_id, role, profile, namespace, remote,
repository_binding, pid, transport, token_fingerprint,
started_at, last_heartbeat_at, heartbeat_ttl_seconds,
fencing_epoch, status, process_identity, instance_id_provenance
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
""",
(
"codex-20260730T070000Z-cccccccccccc",
"codex",
"inst-2",
"s2",
"gen-fence",
"reviewer",
"prgs-reviewer",
"reviewer",
"prgs",
"/repo/Gitea-Tools",
72,
None,
None,
mwi._ts(NOW), # noqa: SLF001
mwi._ts(NOW), # noqa: SLF001
TTL,
1, # same epoch as first (first got epoch 1)
mwi.STATUS_ACTIVE,
"pid-72",
fleet.INSTANCE_ID_PROVENANCE_TRUSTED,
),
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertTrue(
{fleet.CLASS_OWNERSHIP_COLLISION, fleet.CLASS_GENERATION_COLLISION}
& classes
)
class ManifestAndEdgeTests(unittest.TestCase):
def test_missing_and_unmanifested(self):
registry = _registry()
live = "inst-live"
expected = "inst-expected-missing"
_register(
registry,
client="codex",
instance=live,
session="s",
generation="g",
namespace="author",
pid=81,
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
expected_manifest=[
{"client_instance_id": expected, "client_type": "codex"},
],
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
self.assertEqual(snap["missing_expected_instance_ids"], [expected])
self.assertEqual(snap["unmanifested_instance_ids"], [live])
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertIn(fleet.CLASS_MISSING, classes)
self.assertIn(fleet.CLASS_UNMANIFESTED, classes)
def test_unknown_client(self):
registry = _registry()
with registry._tx() as conn: # noqa: SLF001
conn.execute(
"""
INSERT INTO worker_registrations (
worker_identity, client_name, client_instance_id, session_id,
generation_id, role, profile, namespace, remote,
repository_binding, pid, transport, token_fingerprint,
started_at, last_heartbeat_at, heartbeat_ttl_seconds,
fencing_epoch, status, process_identity, instance_id_provenance
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
""",
(
"unknown_client-20260730T070000Z-dddddddddddd",
"unknown_client",
"inst-unk",
"s",
"g",
"author",
"prgs-author",
"author",
"prgs",
"/repo/Gitea-Tools",
91,
None,
None,
mwi._ts(NOW), # noqa: SLF001
mwi._ts(NOW), # noqa: SLF001
TTL,
1,
mwi.STATUS_ACTIVE,
"pid-91",
fleet.INSTANCE_ID_PROVENANCE_TRUSTED,
),
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertIn(fleet.CLASS_UNKNOWN_CLIENT, classes)
def test_foreign_repository(self):
registry = _registry()
_register(
registry,
client="codex",
instance="inst-fr",
session="s",
generation="g",
namespace="author",
pid=101,
repository_binding="/other/repo",
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
canonical_repository="/repo/Gitea-Tools",
)
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertIn(fleet.CLASS_FOREIGN_REPOSITORY, classes)
def test_old_revision(self):
registry = _registry()
_register(
registry,
client="codex",
instance="inst-old",
session="s",
generation="g",
namespace="author",
pid=111,
startup_revision="rev-old",
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
expected_live_revision="rev-live",
)
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertIn(fleet.CLASS_OLD_REVISION, classes)
def test_stale_worker(self):
registry = _registry()
_register(
registry,
client="codex",
instance="inst-stale",
session="s",
generation="g",
namespace="author",
pid=121,
now=NOW,
ttl=60.0,
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=120),
pid_alive_probe=_dead,
)
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertIn(fleet.CLASS_STALE_WORKER, classes)
def test_historical_not_active_blocker(self):
registry = _registry()
_register(
registry,
client="codex",
instance="inst-hist",
session="s",
generation="g",
namespace="author",
pid=131,
status_after=mwi.STATUS_RELEASED,
)
_register(
registry,
client="codex",
instance="inst-live",
session="s2",
generation="g2",
namespace="author",
pid=132,
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(status=None),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
self.assertEqual(snap["historical_worker_count"], 1)
self.assertTrue(
all(f["classification"] == fleet.CLASS_HISTORICAL for f in snap["historical_findings"])
)
# Only historical finding for the dead row — live fleet otherwise safe.
hist_blockers = [
f
for f in snap["active_blockers"]
if f["classification"] == fleet.CLASS_HISTORICAL
]
self.assertEqual(hist_blockers, [])
self.assertTrue(snap["live_fleet_safe"])
def test_legacy_incomplete_identity(self):
registry = _registry()
_register(
registry,
client="codex",
instance="pid-999",
session="s",
generation="g",
namespace="author",
pid=141,
instance_id_provenance=fleet.INSTANCE_ID_PROVENANCE_LEGACY,
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
classes = {f["classification"] for f in snap["active_blockers"]}
self.assertIn(fleet.CLASS_LEGACY_INCOMPLETE, classes)
self.assertFalse(snap["mutation_safe"])
class LifecycleTests(unittest.TestCase):
def test_heartbeat_continuity_across_snapshots(self):
registry = _registry()
outcome = _register(
registry,
client="codex",
instance="inst-hb",
session="s",
generation="g",
namespace="author",
pid=151,
)
identity = outcome["identity"]
earlier = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
later_time = NOW + timedelta(seconds=30)
registry.heartbeat(
worker_identity=identity,
fencing_epoch=outcome["fencing_epoch"],
now=later_time,
expected_session_id="s",
expected_generation_id="g",
expected_client_name="codex",
expected_pid=151,
)
later = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=later_time + timedelta(seconds=1),
pid_alive_probe=_alive,
)
cmp = fleet.compare_snapshot_heartbeats(earlier, later)
self.assertTrue(cmp["stable_ownership"])
self.assertEqual(cmp["shared_live_workers"], [identity])
self.assertTrue(cmp["continuity"][0]["heartbeat_non_decreasing"])
def test_worker_reconnect_preserves_instance(self):
"""Reconnect = heartbeat renew; same instance/worker/session."""
registry = _registry()
o = _register(
registry,
client="codex",
instance="inst-rc",
session="s-rc",
generation="g-rc",
namespace="author",
pid=161,
)
before = registry.get(o["identity"])
registry.heartbeat(
worker_identity=o["identity"],
fencing_epoch=o["fencing_epoch"],
now=NOW + timedelta(seconds=20),
expected_session_id="s-rc",
expected_generation_id="g-rc",
expected_client_name="codex",
expected_pid=161,
)
after = registry.get(o["identity"])
self.assertEqual(before["client_instance_id"], after["client_instance_id"])
self.assertEqual(before["session_id"], after["session_id"])
self.assertEqual(before["worker_identity"], after["worker_identity"])
def test_worker_restart_new_worker_same_instance(self):
registry = _registry()
inst = "inst-restart"
old = _register(
registry,
client="codex",
instance=inst,
session="s-old",
generation="g-old",
namespace="author",
pid=171,
)
registry.release(worker_identity=old["identity"], now=NOW + timedelta(seconds=5))
new = _register(
registry,
client="codex",
instance=inst,
session="s-new",
generation="g-new",
namespace="author",
pid=172,
now=NOW + timedelta(seconds=10),
)
self.assertTrue(new["registered"])
self.assertNotEqual(old["identity"], new["identity"])
snap = fleet.snapshot_instance_fleet(
registry.list_workers(status=None),
now=NOW + timedelta(seconds=15),
pid_alive_probe=_alive,
)
live = [w for w in snap["live_workers"] if w["client_instance_id"] == inst]
self.assertEqual(len(live), 1)
self.assertEqual(live[0]["worker_identity"], new["identity"])
self.assertEqual(snap["historical_worker_count"], 1)
def test_full_application_restart_new_instance(self):
registry = _registry()
old_inst = fleet.generate_client_instance_id("codex", launch_nonce="old", now=NOW)
new_inst = fleet.generate_client_instance_id(
"codex", launch_nonce="new", now=NOW + timedelta(hours=1)
)
for ns, pid in zip(NAMESPACES, range(181, 186)):
o = _register(
registry,
client="codex",
instance=old_inst,
session=f"old-{ns}",
generation=f"oldg-{ns}",
namespace=ns,
pid=pid,
)
registry.release(worker_identity=o["identity"], now=NOW + timedelta(minutes=1))
for ns, pid in zip(NAMESPACES, range(191, 196)):
_register(
registry,
client="codex",
instance=new_inst,
session=f"new-{ns}",
generation=f"newg-{ns}",
namespace=ns,
pid=pid,
now=NOW + timedelta(minutes=2),
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(status=None),
now=NOW + timedelta(minutes=3),
pid_alive_probe=_alive,
)
live_ids = {i["client_instance_id"] for i in snap["instances"]}
self.assertEqual(live_ids, {new_inst})
self.assertEqual(snap["historical_worker_count"], 5)
class PermissionAndSingleClientTests(unittest.TestCase):
def test_single_client_still_supported(self):
registry = _registry()
_five_workers(
registry,
client="codex",
instance="inst-single",
session_prefix="solo",
gen_prefix="solo-g",
pid_base=300,
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
self.assertEqual(snap["instance_count"], 1)
self.assertEqual(snap["live_worker_count"], 5)
self.assertTrue(snap["live_fleet_safe"])
self.assertTrue(snap["mutation_safe"])
def test_snapshot_has_consistency_token(self):
registry = _registry()
_register(
registry,
client="codex",
instance="inst-tok",
session="s",
generation="g",
namespace="author",
pid=400,
)
snap = fleet.snapshot_instance_fleet(
registry.list_workers(),
now=NOW + timedelta(seconds=1),
pid_alive_probe=_alive,
)
self.assertTrue(snap["consistency_token"].startswith("fleetrev-"))
self.assertEqual(snap["consistency_token"], snap["registry_revision"])
self.assertIn("snapshot_at", snap)
def test_tool_role_gate_denies_author(self):
import gitea_mcp_server as server
with mock.patch.object(server, "_profile_operation_gate", return_value=[]):
with mock.patch.object(
server,
"get_profile",
return_value={
"profile_name": "prgs-author",
"role": "author",
"allowed_operations": ["gitea.read"],
"forbidden_operations": [],
},
):
result = server.gitea_snapshot_instance_fleet(remote="prgs")
self.assertFalse(result.get("success"))
self.assertEqual(result.get("denied_role"), "author")
self.assertTrue(result.get("read_only"))
self.assertFalse(result.get("mutation_performed", True))
def test_tool_allows_controller(self):
import gitea_mcp_server as server
registry = _registry()
_register(
registry,
client="codex",
instance="inst-ctrl",
session="s",
generation="g",
namespace="controller",
pid=410,
)
with mock.patch.object(server, "_profile_operation_gate", return_value=[]):
with mock.patch.object(
server,
"get_profile",
return_value={
"profile_name": "prgs-controller",
"role": "controller",
"allowed_operations": ["gitea.read"],
"forbidden_operations": [],
},
):
with mock.patch.object(server, "_worker_registry", return_value=registry):
with mock.patch.object(
server, "_current_master_parity", return_value={}
):
result = server.gitea_snapshot_instance_fleet(remote="prgs")
self.assertTrue(result.get("success"), result)
self.assertTrue(result.get("read_only"))
self.assertTrue(result["permission_scope"]["denied_unrelated_mutations"])
self.assertEqual(result["permission_scope"]["granted_operations"], ["gitea.read"])
def test_tool_allows_reconciler(self):
import gitea_mcp_server as server
registry = _registry()
with mock.patch.object(server, "_profile_operation_gate", return_value=[]):
with mock.patch.object(
server,
"get_profile",
return_value={
"profile_name": "prgs-reconciler",
"role": "reconciler",
"allowed_operations": ["gitea.read"],
"forbidden_operations": [],
},
):
with mock.patch.object(server, "_worker_registry", return_value=registry):
with mock.patch.object(
server, "_current_master_parity", return_value={}
):
result = server.gitea_snapshot_instance_fleet(remote="prgs")
self.assertTrue(result.get("success"), result)
def test_capability_map_entry(self):
import task_capability_map as tcm
entry = tcm.TASK_CAPABILITY_MAP["snapshot_instance_fleet"]
self.assertEqual(entry["permission"], "gitea.read")
self.assertEqual(entry["role"], "controller")
self.assertIn("gitea_snapshot_instance_fleet", tcm.TASK_CAPABILITY_MAP)
def test_fleet_run_env_allowlisted(self):
import gitea_config
self.assertIn("GITEA_MCP_FLEET_RUN_ID", gitea_config.RECOGNIZED_GITEA_ENV_KEYS)
def test_docs_exist(self):
root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
path = os.path.join(root, "docs", "instance-fleet-identity.md")
self.assertTrue(os.path.isfile(path))
with open(path, encoding="utf-8") as fh:
text = fh.read()
self.assertIn("client_instance_id", text)
self.assertIn("exactly_one_per_profile", text)
self.assertIn("gitea_snapshot_instance_fleet", text)
def test_tool_is_registered(self):
import gitea_mcp_server as server
self.assertTrue(callable(server.gitea_snapshot_instance_fleet))
src = inspect.getsource(server.gitea_snapshot_instance_fleet)
self.assertIn("controller", src)
self.assertIn("reconciler", src)
class ClientHintsTests(unittest.TestCase):
def test_client_hints_legacy_when_unset(self):
import gitea_mcp_server as server
env = {"GITEA_MCP_CLIENT": "codex"}
with mock.patch.dict(os.environ, env, clear=False):
# Ensure instance key is absent.
os.environ.pop("GITEA_MCP_CLIENT_INSTANCE", None)
hints = server._client_identity_hints()
self.assertFalse(hints["instance_identity_trusted"])
self.assertTrue(
str(hints["client_instance_id"]).startswith("legacy-pid-")
or hints["instance_id_provenance"] == fleet.INSTANCE_ID_PROVENANCE_LEGACY
)
def test_client_hints_trusted_when_set(self):
import gitea_mcp_server as server
inst = fleet.generate_client_instance_id("codex", launch_nonce="t", now=NOW)
with mock.patch.dict(
os.environ,
{
"GITEA_MCP_CLIENT": "codex",
"GITEA_MCP_CLIENT_INSTANCE": inst,
"GITEA_MCP_FLEET_RUN_ID": "run-1",
},
clear=False,
):
hints = server._client_identity_hints()
self.assertTrue(hints["instance_identity_trusted"])
self.assertEqual(hints["client_instance_id"], inst)
self.assertEqual(hints["fleet_run_id"], "run-1")
def test_malformed_user_supplied_instance_not_trusted(self):
import gitea_mcp_server as server
with mock.patch.dict(
os.environ,
{
"GITEA_MCP_CLIENT": "codex",
"GITEA_MCP_CLIENT_INSTANCE": "user-spoofed-not-launcher",
},
clear=False,
):
hints = server._client_identity_hints()
self.assertFalse(hints["instance_identity_trusted"])
self.assertEqual(hints["client_instance_id"], "user-spoofed-not-launcher")
class ProductionLauncherB1Tests(unittest.TestCase):
"""#978 review 655 B1: production launcher mints + propagates instance ID."""
def test_one_launch_shares_id_across_five_namespaces(self):
import mcp_application_launcher as launcher
profiles = {ns: f"prgs-{ns}" for ns in NAMESPACES}
built = launcher.build_application_mcp_servers(
profiles,
client_type="codex",
config_path="/cfg/profiles.json",
launch_nonce="launch-one",
now=NOW,
command="/venv/bin/python3",
args=["mcp_server.py"],
)
servers = built["mcpServers"]
self.assertEqual(len(servers), 5)
ids = {
servers[f"gitea-{ns}"]["env"]["GITEA_MCP_CLIENT_INSTANCE"]
for ns in NAMESPACES
}
self.assertEqual(len(ids), 1, ids)
shared = next(iter(ids))
self.assertTrue(fleet.assess_instance_identity(shared)["trusted"])
self.assertEqual(built["client_instance_id"], shared)
# No legacy placeholder on any production worker env.
for ns in NAMESPACES:
env = servers[f"gitea-{ns}"]["env"]
self.assertEqual(env["GITEA_MCP_CLIENT_INSTANCE"], shared)
self.assertEqual(
env["GITEA_MCP_INSTANCE_PROVENANCE"],
fleet.INSTANCE_ID_PROVENANCE_TRUSTED,
)
self.assertEqual(env["GITEA_MCP_CLIENT"], "codex")
self.assertEqual(env["GITEA_CLIENT_MANAGED"], "1")
self.assertFalse(env["GITEA_MCP_CLIENT_INSTANCE"].startswith("legacy-"))
proof = launcher.collect_instance_ids_from_mcp_servers(servers)
self.assertTrue(proof["shared_single_trusted_id"], proof)
def test_two_launches_receive_different_ids(self):
import mcp_application_launcher as launcher
profiles = {ns: f"prgs-{ns}" for ns in NAMESPACES}
a = launcher.build_application_mcp_servers(
profiles,
client_type="codex",
launch_nonce="L1",
now=NOW,
command="python3",
args=["mcp_server.py"],
)
b = launcher.build_application_mcp_servers(
profiles,
client_type="codex",
launch_nonce="L2",
now=NOW,
command="python3",
args=["mcp_server.py"],
)
self.assertNotEqual(a["client_instance_id"], b["client_instance_id"])
def test_resume_reuses_supplied_trusted_id(self):
import mcp_application_launcher as launcher
profiles = {ns: f"prgs-{ns}" for ns in NAMESPACES}
first = launcher.build_application_mcp_servers(
profiles,
client_type="claude_code",
launch_nonce="resume-src",
now=NOW,
command="python3",
args=["mcp_server.py"],
)
resumed = launcher.build_application_mcp_servers(
profiles,
client_type="claude_code",
client_instance_id=first["client_instance_id"],
command="python3",
args=["mcp_server.py"],
)
self.assertEqual(first["client_instance_id"], resumed["client_instance_id"])
def test_refuses_untrusted_instance_id_on_production_path(self):
import mcp_application_launcher as launcher
profiles = {ns: f"prgs-{ns}" for ns in NAMESPACES}
with self.assertRaises(ValueError):
launcher.build_application_mcp_servers(
profiles,
client_type="codex",
client_instance_id="pid-999",
command="python3",
args=["mcp_server.py"],
)
with self.assertRaises(ValueError):
launcher.namespace_worker_env(
profile_name="prgs-author",
client_type="codex",
client_instance_id="user-supplied-garbage",
)
def test_extra_env_cannot_override_trusted_instance_keys(self):
import mcp_application_launcher as launcher
trusted = fleet.generate_client_instance_id(
"codex", launch_nonce="seal", now=NOW
)
env = launcher.namespace_worker_env(
profile_name="prgs-author",
client_type="codex",
client_instance_id=trusted,
extra_env={
"GITEA_MCP_CLIENT_INSTANCE": "inst-spoofed-20260730T000000Z-deadbeefdead",
"GITEA_MCP_INSTANCE_PROVENANCE": "trusted_launcher",
"GITEA_CLIENT_MANAGED": "0",
"GITEA_MCP_CLIENT": "gemini",
"GITEA_AUTHOR_WORKTREE": "/ok/extra",
},
)
self.assertEqual(env["GITEA_MCP_CLIENT_INSTANCE"], trusted)
self.assertEqual(env["GITEA_CLIENT_MANAGED"], "1")
self.assertEqual(env["GITEA_MCP_CLIENT"], "codex")
self.assertEqual(env["GITEA_AUTHOR_WORKTREE"], "/ok/extra")
def test_gitea_config_launcher_entry_uses_production_path(self):
"""Production launcher_entry — not a test helper — mints trusted IDs."""
import gitea_config
entry_a = gitea_config.launcher_entry(
"prgs-author",
"/cfg/profiles.json",
client_type="codex",
launch_nonce="cfg-a",
)["gitea-tools"]
entry_b = gitea_config.launcher_entry(
"prgs-author",
"/cfg/profiles.json",
client_type="codex",
launch_nonce="cfg-b",
)["gitea-tools"]
id_a = entry_a["env"]["GITEA_MCP_CLIENT_INSTANCE"]
id_b = entry_b["env"]["GITEA_MCP_CLIENT_INSTANCE"]
self.assertNotEqual(id_a, id_b)
self.assertTrue(fleet.assess_instance_identity(id_a)["trusted"])
self.assertTrue(fleet.assess_instance_identity(id_b)["trusted"])
def test_multi_namespace_launcher_entries_api(self):
import gitea_config
profiles = {ns: f"prgs-{ns}" for ns in NAMESPACES}
built = gitea_config.multi_namespace_launcher_entries(
profiles,
client_type="grok",
config_path="/cfg/profiles.json",
launch_nonce="multi-api",
)
self.assertTrue(built["shared_instance_id_across_namespaces"])
self.assertEqual(built["namespace_count"], 5)
proof = __import__(
"mcp_application_launcher", fromlist=["*"]
).collect_instance_ids_from_mcp_servers(built["mcpServers"])
self.assertTrue(proof["shared_single_trusted_id"], proof)
def test_malformed_and_missing_fail_safely(self):
self.assertFalse(fleet.assess_instance_identity("")["trusted"])
self.assertFalse(fleet.assess_instance_identity(None)["trusted"])
self.assertFalse(fleet.assess_instance_identity("legacy-pid-1")["trusted"])
self.assertFalse(fleet.assess_instance_identity("not-an-inst-id")["trusted"])
self.assertFalse(fleet.assess_instance_identity("inst-")["trusted"])
self.assertFalse(fleet.assess_instance_identity("user-spoofed")["trusted"])
# Reserved inst- prefix from the launcher is trusted.
self.assertTrue(fleet.assess_instance_identity("inst-codex-1")["trusted"])
class InstanceAwareMutationGateB2Tests(unittest.TestCase):
"""#978 review 655 B2: mutation gate is instance-aware, not profile-only."""
def _ps_lines(self, rows):
# rows: list of (pid, lstart, command) — command ignored beyond mcp_server.py
header = " PID LSTART COMMAND\n"
body = "".join(
f"{pid} {lstart} /path/to/python mcp_server.py\n"
for pid, lstart, _env in rows
)
return header + body
def _side_effect(self, rows, *, self_pid=1000):
ps_out = self._ps_lines(rows)
env_by_pid = {str(pid): env for pid, _ls, env in rows}
def side_effect(args, **kwargs):
mock_run = mock.MagicMock()
if args[0] == "ps" and "eww" in args:
mock_run.stdout = env_by_pid.get(str(args[2]), "")
return mock_run
if args[0] == "ps":
mock_run.stdout = ps_out
return mock_run
if args[0] == "git":
mock_run.stdout = "deadbeef"
return mock_run
raise ValueError(args)
return side_effect
def test_two_valid_instances_same_profile_allowed(self):
import gitea_mcp_server as server
inst_a = fleet.generate_client_instance_id(
"codex", launch_nonce="gate-a", now=NOW
)
inst_b = fleet.generate_client_instance_id(
"codex", launch_nonce="gate-b", now=NOW
)
lstart = "Wed Jul 8 15:00:00 2026"
rows = [
(
2001,
lstart,
(
f"GITEA_MCP_PROFILE=prgs-author GITEA_CLIENT_MANAGED=1 "
f"GITEA_MCP_CLIENT_INSTANCE={inst_a} "
f"GITEA_MCP_WORKER_IDENTITY=worker-a "
f"GITEA_MCP_GENERATION_ID=gen-a"
),
),
(
2002,
lstart,
(
f"GITEA_MCP_PROFILE=prgs-author GITEA_CLIENT_MANAGED=1 "
f"GITEA_MCP_CLIENT_INSTANCE={inst_b} "
f"GITEA_MCP_WORKER_IDENTITY=worker-b "
f"GITEA_MCP_GENERATION_ID=gen-b"
),
),
]
with mock.patch("subprocess.run") as mock_run, mock.patch(
"os.path.getmtime", return_value=datetime(2026, 7, 8, 11, 0, 0).timestamp()
), mock.patch("os.path.exists", return_value=True), mock.patch(
"os.getpid", return_value=9999
):
mock_run.side_effect = self._side_effect(rows)
reasons = server._check_mcp_runtimes_diagnostics(
"create_issue", ["prgs-author"]
)
self.assertFalse(
any("Duplicate MCP server process(es) detected" in r for r in reasons),
reasons,
)
def test_duplicate_same_instance_and_namespace_blocked(self):
import gitea_mcp_server as server
inst = fleet.generate_client_instance_id(
"codex", launch_nonce="dup", now=NOW
)
lstart = "Wed Jul 8 15:00:00 2026"
rows = [
(
3001,
lstart,
(
f"GITEA_MCP_PROFILE=prgs-author GITEA_CLIENT_MANAGED=1 "
f"GITEA_MCP_CLIENT_INSTANCE={inst} "
f"GITEA_MCP_WORKER_IDENTITY=worker-1 "
f"GITEA_MCP_GENERATION_ID=gen-1"
),
),
(
3002,
lstart,
(
f"GITEA_MCP_PROFILE=prgs-author GITEA_CLIENT_MANAGED=1 "
f"GITEA_MCP_CLIENT_INSTANCE={inst} "
f"GITEA_MCP_WORKER_IDENTITY=worker-2 "
f"GITEA_MCP_GENERATION_ID=gen-2"
),
),
]
with mock.patch("subprocess.run") as mock_run, mock.patch(
"os.path.getmtime", return_value=datetime(2026, 7, 8, 11, 0, 0).timestamp()
), mock.patch("os.path.exists", return_value=True), mock.patch(
"os.getpid", return_value=9999
):
mock_run.side_effect = self._side_effect(rows)
reasons = server._check_mcp_runtimes_diagnostics(
"create_issue", ["prgs-author"]
)
self.assertTrue(
any("Duplicate MCP server process(es) detected" in r for r in reasons),
reasons,
)
self.assertTrue(
any("duplicate namespace" in r.lower() or "client_instance_id" in r for r in reasons),
reasons,
)
def test_missing_instance_evidence_still_fail_closed(self):
"""Two profile-sharing processes without trusted IDs remain blocked."""
import gitea_mcp_server as server
lstart = "Wed Jul 8 15:00:00 2026"
rows = [
(
4001,
lstart,
"GITEA_MCP_PROFILE=prgs-author GITEA_CLIENT_MANAGED=1",
),
(
4002,
lstart,
"GITEA_MCP_PROFILE=prgs-author GITEA_CLIENT_MANAGED=1",
),
]
with mock.patch("subprocess.run") as mock_run, mock.patch(
"os.path.getmtime", return_value=datetime(2026, 7, 8, 11, 0, 0).timestamp()
), mock.patch("os.path.exists", return_value=True), mock.patch(
"os.getpid", return_value=9999
):
mock_run.side_effect = self._side_effect(rows)
reasons = server._check_mcp_runtimes_diagnostics(
"create_issue", ["prgs-author"]
)
self.assertTrue(
any("Duplicate MCP server process(es) detected" in r for r in reasons),
reasons,
)
def test_single_instance_still_ok(self):
import gitea_mcp_server as server
inst = fleet.generate_client_instance_id(
"codex", launch_nonce="single", now=NOW
)
lstart = "Wed Jul 8 15:00:00 2026"
rows = [
(
5001,
lstart,
(
f"GITEA_MCP_PROFILE=prgs-author GITEA_CLIENT_MANAGED=1 "
f"GITEA_MCP_CLIENT_INSTANCE={inst} "
f"GITEA_MCP_WORKER_IDENTITY=worker-only "
f"GITEA_MCP_GENERATION_ID=gen-only"
),
),
]
with mock.patch("subprocess.run") as mock_run, mock.patch(
"os.path.getmtime", return_value=datetime(2026, 7, 8, 11, 0, 0).timestamp()
), mock.patch("os.path.exists", return_value=True), mock.patch(
"os.getpid", return_value=9999
):
mock_run.side_effect = self._side_effect(rows)
reasons = server._check_mcp_runtimes_diagnostics(
"create_issue", ["prgs-author"]
)
self.assertFalse(
any("Duplicate MCP server process(es) detected" in r for r in reasons),
reasons,
)
if __name__ == "__main__":
unittest.main()