ADR-0222shipped

Prompt-Layer Role Matrix and Session Handles

Context

The prompt stack had the right pieces but the hierarchy was still too fuzzy in practice.

Problems observed:

  1. SYSTEM.md said identity came from layered files, but it did not explain the hierarchy clearly enough for agents to reason about who they are in a session.
  2. roles/system.md existed and ~/.joelclaw/ROLE.md already pointed at it, but the mental model around system vs interactive was drifting.
  3. Agent-to-agent coordination (joelclaw mail) and operator relay (joelclaw notify → gateway → Joel) were not stated sharply enough, so the transport split was muddy.
  4. System sessions lacked a session-local identifier. Reusing the same stable agent name makes mail, logs, and operator summaries harder to attribute to a specific session.

Decision

1. Make the prompt-layer hierarchy explicit in SYSTEM.md

SYSTEM.md now states the layer order and purpose of each layer:

SYSTEM.md
  → IDENTITY.md
  → SOUL.md
  → ROLE.md
  → USER.md
  → TOOLS.md
  → AGENTS.md
  → skills

The key rule is:

  • identity is stable
  • role is contextual
  • session handles are local identifiers only

2. Canonical role matrix

The system recognizes these role contracts:

  • system — default interactive pi role on Panda
  • gateway — operator-facing orchestration/triage
  • codex-worker — bounded implementation worker
  • loop-worker — pipeline implementation worker
  • voice — conversational capture/synthesis
  • interactive — legacy alias; prefer system

Role selection remains resolved by identity-inject via:

  1. JOELCLAW_ROLE_FILE
  2. JOELCLAW_ROLE
  3. GATEWAY_ROLE=central
  4. fallback ~/.joelclaw/ROLE.md

3. Split coordination transport from operator relay

This distinction is now explicit:

  • joelclaw mail = agent coordination, reservations, handoffs
  • joelclaw notify = gateway/operator relay

The system role sends operator-facing progress/status packets through the gateway, not through ad hoc direct channel assumptions.

4. System-session relay policy

For non-trivial work, system sessions should send concise relay packets:

  • at start
  • on major state changes (delegated, blocked, recovered, done)
  • periodically during long active work

Relay packets should include, when relevant:

  • session handle
  • current objective
  • touched surfaces
  • notable memory or slog references
  • desired system improvements
  • blockers / risks
  • next move

Gateway remains the final router and applies ADR-0189 before anything reaches Joel.

5. Session-local handles for system sessions

pi/extensions/session-lifecycle/index.ts generates a session-local handle for system sessions.

Properties:

  • compact AdjectiveNoun identifier
  • derived from session context, with a slightly funny/system-flavoured tone
  • shown in the session identity block
  • intended for joelclaw mail --agent <handle> / mail_* agent parameters, logs, handoffs, and relay packets
  • does not replace the stable identity or role

Implementation Plan

Required skills before implementation

  • system-prompt — prompt-layer design and anti-pattern avoidance
  • clawmail — coordination vs relay transport split
  • adr-skill — ADR shape and consequences

Affected paths

  • SYSTEM.md
  • roles/system.md
  • docs/gateway.md
  • docs/prompt-architecture.md
  • pi/extensions/session-lifecycle/index.ts

Pattern

  • keep universal prompt law in SYSTEM.md
  • keep role-specific behaviour in roles/system.md
  • use docs to explain the matrix explicitly
  • use session-lifecycle to inject per-session identity metadata without mutating stable identity

Verification

  • SYSTEM.md explains prompt-layer hierarchy and role matrix explicitly
  • system role documents gateway relay policy
  • docs distinguish mail from notify
  • prompt architecture doc exists and matches reality
  • session-lifecycle generates and surfaces session-local handles for system sessions
  • session handoff includes the generated handle when present

Consequences

  • Agents have a clearer answer to “who am I right now?”
  • system becomes the explicit default interactive role instead of an implied alias
  • Gateway becomes the clean operator relay path for system-session progress
  • Mail traffic and logs gain better per-session attribution
  • Stable identity stays stable; session handles add precision without creating role drift