Skip to content

README: Team

Profile version: net.plantange/v1 Kind: team Surface root: team::<team_id>/


What is a Team?

A Team is a brand-bound, lightweight identity projection construct. It publishes a catalog of Slogans — small, portable projection units — that attached agents may emit into permitted contexts.

Key design properties:

  • No mandate required. A Team exists and publishes without governance authority.
  • No arbitration. Teams do not adjudicate competing claims.
  • No state mutation. Emitting a slogan creates no obligation on the agent.
  • Opt-in attachment. Agents attach and detach freely; attachment grants projection rights.
  • Multiple Teams coexist. Teams may overlap without conflict.

The Team is the lightweight end of the social hierarchy. Fate and League sit above it; Team itself is just identity + catalog.


Three Concepts

Team          — brand identity + slogan catalog + optional per-agent cap
Slogan        — lightweight, portable, non-binding projection unit
TeamAttachment — agent opt-in to a Team; grants "we" identity

A ProjectionRequest is: agent + team + slogan + context. validate_projection() checks attachment, catalog, context, and cap — in that order.


Surface Organisation

team::<team_id>/
  identity/
    team_id    brand_id    name    description
  slogans[]
    slogan_id    text
    allowed_contexts[]
    ttl_frames          (optional)
    coherence_hint      [0.0, 1.0]
  max_active_slogans    (optional, soft cap)
  attachments/
    count               — current attached agent count
  projections/          (full view only)
    accepted    rejected
    last_rejection_reason
  spec/
    ref    genome
  engine/
    name    version
  view
  frame

Key Properties

Slogan Catalog (slogans)

The complete set of projection units this team publishes. Each slogan:

  • Has a stable slogan_id within this team.
  • Has a text — the projection string (e.g. "We sweep together.").
  • May restrict allowed_contexts — empty = all contexts permitted.
  • May carry ttl_frames — optional frame lifetime; omit for no expiry.
  • Carries coherence_hint [0.0, 1.0] — advisory only. 1.0 = tight team identity assertion; lower = ambiguous or ironic. Not enforced.

Attachment (attachments/count)

The number of agents currently attached. The full agent list is coordinator state (TeamAttachmentRegistry), not a KNAT surface. Monitor count to confirm the team has active participants.

Projection Gate (validate_projection)

Four checks in order:

  1. Is the agent attached to the team? (NotAttached if not)
  2. Does the slogan exist in the catalog? (SloganNotFound if not)
  3. Does the slogan permit the context? (ContextNotPermitted if not)
  4. Is the agent under the per-agent cap? (CapExceeded if over)

projections.last_rejection_reason shows the most recent failure mode.


Relation to League

A Team that wants to project through a League's template catalog must be enrolled in that League. The validation chain then adds League-side checks (enrollment, template existence, slot validity) on top of the Team-side checks.

See League for the full League surface.


MVP Presence

A minimal valid Team KNAT snapshot:

  • id, frame, engine, view
  • identity.team_id, identity.brand_id, identity.name
  • slogans (may be empty array)
  • attachments.count
  • spec.ref, spec.genome

Example: Slug Bears

{
  "id": "slug-bears",
  "spec": {
    "ref": "file://brands/teams/slug_bears/spec.json",
    "genome": "aabb1122ccdd3344"
  },
  "engine": { "name": "janet-executor", "version": "0.4.0" },
  "view": "full",
  "frame": 900,
  "identity": {
    "team_id": "slug-bears",
    "brand_id": "slug-bears",
    "name": "Slug Bears",
    "description": "Process-first, continuity-first."
  },
  "slogans": [
    {
      "slogan_id": "patience",
      "text": "We sweep together.",
      "allowed_contexts": ["curling"],
      "coherence_hint": 1.0
    },
    {
      "slogan_id": "anywhere",
      "text": "Process prevails.",
      "allowed_contexts": [],
      "coherence_hint": 0.8
    }
  ],
  "max_active_slogans": 3,
  "attachments": {
    "count": 12
  },
  "projections": {
    "accepted": 47,
    "rejected": 2,
    "last_rejection_reason": "ContextNotPermitted"
  }
}