Data Observer vs. Data Agent

This reference document aims to provide a side-by-side look at Observers (data-observer) and Agents (data-agent) in Blocktail. Remember, each has its own purpose and scope, yet they collaborate within the Behavioral Layer System—whether you’re coding in plain HTML or a framework like React, Vue, or Angular.

Separation of Concerns

  1. Observer: Owns a single block (L3), controlling states/mutations (e.g., --dark_mode, --streaming).
  2. Agent: Applies utility behaviors anywhere—system, context, block, or tail—without messing with block sovereignty.

Clear Ownership

  1. A block’s observer is the “single source of truth” for its lifecycle and states.
  2. Agents do not touch the block’s states, so collisions rarely occur.

Key Differences at a Glance

Copy link to this section
FeatureObserverAgent
PurposeManage block lifecycle & states (mutations)Add utility or cross-layer behavior
ScopeBlock level (L3) onlyAny layer (L1–L5)
SovereigntyYes (one observer per block)No (never claims a block)
State ControlHandles mutations like --dark_mode, --streamingDoes not handle block mutations
Lifecycle Eventsinit(), destroy(), etc. for the blockOptional init/destroy, but no block ownership
CompositionCan embed “internal modules” or agents internallyUsually self-contained or combined with others
Conflict RiskIf multiple Observers attach to the same blockMinimal (only if multiple Agents do the same job)
Exampledata-observer="HeroObserver"data-agent="ParallaxScroll"

Pattern Evolution & Valid Paths

Copy link to this section

1. System-Level Agent + Block Observer

Copy link to this section
<body class="matrix--marketing_portal"      <!-- L1: System -->
      data-agent="GlobalAnalytics">         <!-- Agent for template-wide tracking -->
  <main class="context--landing_page"       <!-- L2: Local context -->
    <section class="hero_banner --dark_mode" <!-- L3 + L4 -->
             data-observer="HeroObserver"  <!-- Observer for this block -->
             data-agent="ParallaxScroll">        <!-- Cross-layer scroll effect -->
      <div class="-intro_text">...</div>     <!-- Tails (L5) -->
    </section>
  </main>
</body>
  • Observer: Controls block states (--dark_mode).
  • Agent: At system level (GlobalAnalytics) plus an Agent at the block (ParallaxScroll).

2. Multiple Agents, Single Observer

Copy link to this section
<article class="live_feed --streaming"
         data-observer="LiveFeedObserver"
         data-agent="FadeInAnimation">
  <div class="-chat_panel"
       data-agent="AutoScroll">
    <!-- Chat messages -->
  </div>
</article>
  • Observer: LiveFeedObserver (handles --streaming states).
  • Agents:
    • FadeInAnimation at the block level
    • AutoScroll at a tail element

3. Context & Mutation Mix

Copy link to this section
<div class="context--premium_users">
  <section class="profile_card --vip_access"
           data-observer="ProfileObserver"
           data-agent="RevealAnimation">
    <h2 class="-username">Jane Doe</h2>
  </section>
</div>
  • Local context context--premium_users.
  • profile_card --vip_access block with a single observer controlling user state + an agent for some animation effect.
LayerObserverAgentComment
L1: MatrixNoYesObservers can’t own <body>, Agents can.
L2: ContextNoYesObservers can’t own <main> or contexts.
L3: BlockYes (1 per block)YesObserver owns block states, Agents add utility.
L4: MutationN/AYes (optional)Agents may respond but don’t define states.
L5: TailNoYesObservers can’t attach to tails; Agents can.

Working Together: Observer + Agent

Copy link to this section
<section class="hero_banner --highlighted"
         data-observer="HeroBannerObserver"
         data-agent="ParallaxScroll">
  <div class="-intro_text">
    <h1 class="-headline">Introducing Our New Feature</h1>
  </div>
</section>
  • Observer: HeroBannerObserver manages block states (--highlighted).
  • Agent: ParallaxScroll is a purely additive effect here.

Tips for Collaboration

  1. Avoid Overlaps: Agents don’t attempt to handle the same states the observer manages.
  2. Shared Lifecycle Hooks: Observers handle block-level events; agents may have an init/destroy but never override the observer’s flow.
  3. Minimal Cross-Talk: Keep each behavioral pattern (observer vs. agent) self-contained.

Example Code Flow

Copy link to this section
<body class="matrix--admin_portal"          <!-- L1 -->
      data-agent="GlobalAnalytics">         <!-- System-level agent -->
  <main class="context--dashboard_panel"    <!-- L2 -->
        data-agent="InfiniteScroll">        <!-- Context-level agent -->
    <article class="live_feed --streaming"  <!-- L3 + L4 -->
             data-observer="LiveFeedObserver"  <!-- Observer for streaming states -->
             data-agent="FadeInAnimation">     <!-- Additional block effect -->
      <div class="-chat_panel"              <!-- L5 -->
           data-agent="AutoScroll">         <!-- Tail-level agent for chat scrolling -->
        <!-- Chat messages go here -->
      </div>
    </article>
  </main>
</body>
  1. Observers (B1):
    • Single block-level authority
    • Handles lifecycle, states (--dark_mode, --featured), resource usage
    • Composes advanced internal behaviors if needed
  2. Agents (B2):
    • Utility at any layer (L1–L5)
    • Never owns block or toggles block states
    • Great for shared or cross-layer enhancements
  3. Predictable Evolution:
    • One observer per block → stable states
    • Agents can appear anywhere → easy additions
    • Large or mission-critical systems remain organized
  4. Framework-Agnostic:
    • HTML attributes keep code flexible in Next.js, React, Vue, Angular, etc.
    • Observers and Agents can map to your component lifecycle if desired
  5. Minimal Confusion:
    • Observers unify block logic; Agents offer purely additive functionality

To reiterate, Observers guarantee each block’s logic remains unified. Agents provide cross-layer enhancements without overshadowing the observer’s domain. This ensures clean layering of advanced features in the Blocktail framework.