Skip to content
This repository was archived by the owner on Feb 27, 2026. It is now read-only.
This repository was archived by the owner on Feb 27, 2026. It is now read-only.

refactor: Unify agent_turn_context and agent_bootstrap_context schema #158

Description

@NOVA-Openclaw

Background

The two context tables (agent_turn_context and agent_bootstrap_context) evolved separately and have inconsistent column naming and constraints. This creates confusion and maintenance overhead.

Current state

agent_turn_context:

  • context_type (UNIVERSAL/GLOBAL/DOMAIN/AGENT)
  • context_key — scope identifier (domain name, agent name, or *)
  • document_name — redundant with context_key since there's only one row per scope
  • Unique: (context_type, document_name)

agent_bootstrap_context:

  • context_type (UNIVERSAL/GLOBAL/DOMAIN/AGENT)
  • domain_name — set for DOMAIN type
  • agent_name — set for AGENT type
  • document_name — distinguishes multiple documents within a scope
  • Unique: (context_type, COALESCE(agent_name, ''), COALESCE(domain_name, ''), document_name)

Problems

  1. context_key vs domain_name/agent_name — same concept, different names
  2. document_name is redundant in turn context (one row per scope)
  3. No enforcement that UNIVERSAL and GLOBAL have only one row each
  4. COALESCE in unique index is ugly — separate columns for the same logical field

Changes

1. agent_turn_context

  • Drop document_name column
  • Rename context_keycontext_name
  • New unique constraint: (context_type, context_name)
  • context_name values: '*' for UNIVERSAL/GLOBAL, domain name for DOMAIN, agent name for AGENT

2. agent_bootstrap_context

  • Drop domain_name and agent_name columns
  • Add context_name column (replaces both)
  • Keep document_name (bootstrap has multiple documents per scope)
  • New unique constraint: (context_type, context_name, document_name)
  • context_name values: '*' for UNIVERSAL/GLOBAL, domain name for DOMAIN, agent name for AGENT

3. Shared pattern

Both tables use context_type + context_name as the scope identifier. Bootstrap adds document_name as a third dimension for multiple documents per scope.

4. Enforce UNIVERSAL/GLOBAL uniqueness

  • agent_turn_context: Add partial unique index — only ONE row where context_type = 'UNIVERSAL', only ONE row where context_type = 'GLOBAL'
  • agent_bootstrap_context: UNIVERSAL/GLOBAL can have multiple rows (multiple documents), but all share context_name = '*'. Uniqueness is already handled by (context_type, context_name, document_name)

5. Update dependent code

  • get_agent_turn_context() function — query uses context_name instead of context_key
  • get_agent_bootstrap() function — query uses context_name instead of domain_name/agent_name
  • protect_bootstrap_context_writes() trigger — references column names
  • agent-turn-context hook (handler.ts) — if it references column names
  • db-bootstrap-context hook (handler.ts) — column name references
  • Logical replication publications (graybeard_sync_pub) — WHERE clauses reference column names
  • Any CHECK constraints referencing old column names

Migration strategy

  • Pre-migration script to populate context_name from existing domain_name/agent_name/context_key
  • Then pgschema handles the structural diff
  • Backward-compatible: existing data preserved, just column renames

Constraints

  • One UNIVERSAL row in agent_turn_context, one GLOBAL row
  • One DOMAIN row per domain name in agent_turn_context
  • One AGENT row per agent name in agent_turn_context
  • Bootstrap allows multiple rows per scope (distinguished by document_name)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions