Skip to content

How-to: Add a new partner class

This guide walks a Phase-1 contributor through adding a new partner class to the CHAMBER zoo. The contract is fixed in Phase 0 — see ADR-009 §Decision — and the steps below are the mechanical end-to-end recipe.

1. Subclass PartnerBase

Every partner inherits from chamber.partners.interface.PartnerBase, which:

  • stores spec (the PartnerSpec the registry passed in);
  • shields the _FORBIDDEN_ATTRS set so the AHT no-joint-training constraint is enforced at runtime even when callers reach for raw torch methods.

Implement reset(*, seed) and act(obs, *, deterministic) to satisfy the FrozenPartner Protocol — that is the entire surface.

2. Register with @register_partner

from chamber.partners import PartnerBase, PartnerSpec, register_partner

@register_partner("my_new_partner")
class MyNewPartner(PartnerBase):
    def reset(self, *, seed: int | None = None) -> None:
        ...

    def act(self, obs, *, deterministic=True):
        ...

The decorator records the class against the string id; double-registration raises ValueError so name collisions are caught at import time.

3. Build instances via load_partner

from chamber.partners import PartnerSpec, load_partner

spec = PartnerSpec(
    class_name="my_new_partner",
    seed=0,
    checkpoint_step=None,
    weights_uri=None,
    extra={"uid": "fetch"},
)
partner = load_partner(spec)

The partner_id (a 16-hex hash of class_name, seed, checkpoint_step, weights_uri) is the stable identity the M3 conformal filter reads from obs["meta"]["partner_id"] to detect mid-episode partner swap (ADR-006 risk #3; ADR-004 §risk-mitigation #2).

4. Property-test the shield

Add a property test that partner.train() (and every other forbidden name) raises AttributeError referencing ADR-009. The existing tests/property/test_no_train_allowed.py covers PartnerBase directly; for new shielded subclasses, mirror that pattern.

5. Read pose from the comm packet

Partners read proprio from obs["agent"][uid] and pose from obs["comm"]["pose"][uid] — the ADR-003 §Decision fixed-format channel. Do not reach into env-specific keys; partners are env-agnostic by design.