Plugin Complexity Tiers

All Levels Choose your starting point

DVP CMS is a truth distillation system for AI-generated content. Plugins are evidence suppliers—they verify facts, pull live data, and make content more trustworthy over time. Learn more →

What Plugins Enable

DVP CMS is a truth distillation system. Content regenerates over time, but verified facts persist while unverified filler gets replaced. Plugins are how you feed evidence into this system.

Every plugin you build is an evidence supplier. When your plugin fetches data from an API, verifies a claim, or checks content quality—it submits evidence to the authority system with full provenance. Over regeneration cycles, this evidence accumulates, and your content converges toward ground truth.

What plugins can do:

  • Verify facts — Cross-reference claims against Wolfram Alpha, Wikipedia, or Google Fact Check
  • Pull live data — Inject weather, stock prices, exchange rates with automatic expiration
  • Check quality — Score readability, find broken links, validate image accessibility
  • Enforce compliance — Detect PII, scan for copyright issues before publishing
  • Trigger workflows — Send Slack alerts, email digests, or webhook notifications

The complexity tier you choose determines how deeply your plugin integrates with the authority system. Simple plugins transform content. Standard plugins fetch and cache external data. Advanced plugins implement the full evidence submission lifecycle.

Complexity Tiers

DVP CMS plugins are organized into three tiers. Start with the tier that matches your needs, then progress as your requirements grow.

New to DVP CMS? Start with the Simple tier. You can build a working plugin in 15 minutes with just 50 lines of code.

Simple Tier

~50 lines 15 minutes

The absolute minimum needed for a working plugin. One hook, no external dependencies, immediate results.

Single hook implementation
No configuration needed
No external dependencies
Minimal boilerplate
Use when: Learning DVP CMS, building prototypes, simple content transformations, quick experiments.

Example: Word Counter Plugin

"""Word Counter Plugin - adds word count to content."""

from __future__ import annotations

from typing import TYPE_CHECKING

from dvp_cms.kernel.plugin import Plugin
from dvp_cms.plugins.hookspec import ContentLifecycleHooks

if TYPE_CHECKING:
    from dvp_cms.kernel.event_bus import EventBus


class WordCounterPlugin(Plugin, ContentLifecycleHooks):
    """Count words in content before creation."""

    plugin_id = "word-counter"
    plugin_version = "1.0.0"
    plugin_name = "Word Counter"
    plugin_description = "Adds word count to content"
    plugin_author = "Your Name"
    plugin_capabilities = ["content_enhancement"]

    def __init__(self, event_bus: EventBus) -> None:
        super().__init__(event_bus)

    async def initialize(self, config: dict[str, object]) -> None:
        self._logger.info("Word counter initialized")

    async def shutdown(self) -> None:
        await self.unsubscribe_all()

    def dvp_before_content_create(
        self,
        content: dict[str, object],
        metadata: dict[str, object] | None = None,
    ) -> dict[str, object]:
        """Add word count before content is created."""
        text = str(content.get("body", ""))
        content["word_count"] = len(text.split())
        return content  # Always return!

Template: View the Simple Template source code.

Standard Tier

~200 lines 1-2 hours

Production-ready patterns for real-world plugins. API integration, caching, error handling, and evidence submission.

Configuration handling
HTTP client management
Response caching with TTL
Error handling patterns
Evidence submission
Resource cleanup
Use when: Building production plugins, integrating with APIs, caching responses, submitting evidence to the authority system.

Key Patterns

# Configuration handling
async def initialize(self, config: dict[str, object]) -> None:
    self._api_key = str(config.get("api_key", ""))
    self._cache_ttl = int(config.get("cache_ttl", 3600))
    self._http_client = httpx.AsyncClient(timeout=30.0)

# Caching with TTL
async def _fetch_data(self, text: str) -> Response | None:
    cache_key = hashlib.sha256(text.encode()).hexdigest()
    cached = self._cache.get(cache_key)
    if cached and not cached.is_expired(self._cache_ttl):
        return cached.data
    # ... fetch fresh data

# Error handling
try:
    response = await self._http_client.get(url)
except httpx.TimeoutException:
    self._logger.warning("API timeout")
    return None
except httpx.HTTPStatusError as e:
    self._logger.warning("HTTP error %d", e.response.status_code)
    return None

Template: View the Standard Template source code.

Advanced Tier

~500+ lines 2-4 hours

The gold standard reference implementation. Every pattern documented, every hook implemented, every mistake warned against.

All hooks implemented
Authority system integration
Async event handling
Cache eviction strategies
Configuration validation
Exhaustive documentation
"DON'T DO THIS" warnings
Complete test coverage
Use when: Learning best practices, building complex integrations, understanding the full plugin architecture, contributing to the DVP CMS ecosystem.

What Makes It Advanced

# Exhaustive documentation
"""
PURPOSE OF THIS FILE
--------------------
This is the GOLD STANDARD reference implementation...

PLUGIN ARCHITECTURE
-------------------
    ┌─────────────────────────────────────────┐
    │            DVP CMS Kernel               │
    │  ┌───────────┐  ┌───────────┐          │
    │  │ EventBus  │  │ Authority │          │
    │  └─────┬─────┘  └─────┬─────┘          │
...
"""

# All hooks with complete docstrings
def dvp_before_content_create(
    self,
    content: dict[str, object],
    metadata: dict[str, object] | None = None,
) -> dict[str, object]:
    """Called synchronously before content is created.

    This is a FILTER HOOK - you MUST return the content dictionary.
    ...

    Warning:
        This hook is SYNCHRONOUS. Do not perform async operations.
    """

# Inline warnings about common mistakes
# ---------------------------------------------------------------
# DON'T DO THIS: Forgetting to return content
# ---------------------------------------------------------------
#
# WRONG - Content is lost!
#
#     def dvp_before_content_create(self, content, metadata=None):
#         content["processed"] = True
#         # forgot to return!
#

Template: View the Advanced Template source code. This is the authoritative reference for all DVP CMS plugin patterns.

Choosing Your Tier

Question Simple Standard Advanced
Do you need external API calls? No Yes Yes
Do you need caching? No Yes Yes
Do you need authority integration? No Optional Yes
Is this for production? Prototyping Yes Yes
Time to build 15 min 1-2 hours 2-4 hours

Progressive Disclosure

The tier system implements progressive disclosure: you learn only what you need, when you need it.

  1. Start Simple - Build your first plugin in 15 minutes. Understand hooks and lifecycle.
  2. Add Features - When you need API integration, copy patterns from Standard tier.
  3. Master the Platform - When building complex plugins, study the Advanced tier for every pattern and pitfall.
LLM-Friendly: The canonical template is designed to work with AI coding assistants. Point your AI at _template-canonical/plugin.py and ask it to build plugins following those patterns.

Reference Plugins

In addition to the templates, DVP CMS includes 16 production-quality reference plugins that demonstrate real-world patterns:

Study these plugins to see how patterns apply to specific use cases.