P1.7 Relationship Block — Two-Layer Architecture
P1.7 is the [RELATIONSHIP CONTEXT] block injected between P1.6 (bot backstory) and P2 (always_remember) in the agent-brain prompt stack. It is assembled by buildRelationshipBlock() in rpe-context-assembler/lib/relationship-block.js.
TWO-LAYER MODEL:
Layer 1 — Channel context: prose describing the social world of the channel. Source: channels.context_modifier (preferred). Non-DM fallback: community.domain.{channels.engagement_domain} from prompt_modifiers. DM channels: only explicit context_modifier qualifies — no fallback. This layer fires even when no relationship_id is set.
Layer 2 — Relationship members: individual relationship notes for participants in this channel. Source: zoey_core.relationship_members WHERE relationship_id = channels.relationship_id. Only fires when BOTH channels.relationship_id IS NOT NULL AND botScopeUuid IS NOT NULL.
Pairs in relationship_members are split into two categories:
- Bot-pairs (one side = botScopeUuid): rendered under "Relationship members:" header. Describes each human member's relationship with the bot.
- User-user pairs (neither side = botScopeUuid): rendered under "Member relationships:" header. Describes dynamics between human members (e.g. jim→sam as intimate partners).
Both pair types are skipped when notes AND context_modifier are both null.
BOT UUID DERIVATION:
botScopeUuid is derived at the rpe-context-assembler call site by JOINing zoey_core.bots ON bots.id = channels.bot_id. Added by migration 016_bots_scope_uuid.sql. The JOIN is in the _loadChannelRow query: SELECT c.*, b.scope_uuid AS bot_scope_uuid FROM zoey_core.channels c LEFT JOIN zoey_core.bots b ON b.id = c.bot_id. This makes the system bot-name-agnostic — no hardcoded Zoey UUID in application code.
GRACEFUL DEGRADATION POLICY:
Every degradation notifies sysops. No degradation is silent.
- botScopeUuid null: Layer 2 skipped, Layer 1 still renders. pino WARN + errorReporter.warning(RELATIONSHIP_BLOCK_NO_BOT_UUID).
- userScopeUuid null: block renders in degraded mode. pino WARN + errorReporter.warning(RELATIONSHIP_BLOCK_NO_SCOPE_UUID).
- context_modifier key missing: that prose block omitted, rest continues. pino WARN only (lib has no errorReporter).
- null return with relationship_id set: errorReporter.warning(RELATIONSHIP_BLOCK_EMPTY_WITH_REL_ID).
CACHING:
Redis key: relationship_block:{realmId}:{chatId} — TTL 300s. Must be cleared after any deploy that changes relationship-block.js, after migration 016, or after changing channel/relationship_members data.
Clear: rdcli -h 192.168.1.151 -p 6379 DEL relationship_block:2:<chat_id>