Skip to content

Acquia Source × Bluefly: Technical Specification

Updated: 2026-04-25 | Status: Active | Owner: Thomas Scola

Production Requirement: An OSSA-compliant system MUST trace every action, attribute every cost, enforce every constraint, and expose every capability via contract.

Invariant: An agent that cannot be traced, cost-attributed, and constrained MUST NOT be deployed.


Kind Enforcement Rules (STRICT)

Three kinds. No exceptions.

Kind MAY define llm MUST define observability + cost_tracking Execution rules
Agent Yes Yes — REQUIRED Bounded autonomy under enforced constraints. Emits trace spans for every decision cycle.
Task No — MUST NOT Yes — REQUIRED Deterministic. No LLM calls. Repeatable given same input.
Workflow No — MUST NOT Yes — REQUIRED Orchestration layer ONLY. MUST NOT execute logic. Composes agents and tasks.

Identity (REQUIRED — All Agents)

spec:
  identity:
    service_name: ""          # REQUIRED — unique agent name
    service_namespace: ""     # REQUIRED — org/domain namespace
    service_version: ""       # REQUIRED — semver
    service_instance_id: ""   # REQUIRED — unique per runtime instance

service_instance_id MUST be unique per runtime instance. No two running instances may share an ID.


Observability (REQUIRED — Not Optional)

spec:
  observability:
    tracing:
      enabled: true           # REQUIRED — no exceptions
    metrics:
      enabled: true           # REQUIRED — no exceptions

Agents MUST emit trace spans for every decision cycle. Metrics MUST include: latency, error rate, cost per execution, step count.


Bounded Autonomy (REQUIRED — All Agents)

constraints:
  execution:
    maxRuntimeSeconds: 300    # Default ceiling — configurable down, not up without escalation
    maxSteps: 50              # Maximum decision cycles per invocation
    timeoutStrategy: abort    # abort | suspend | escalate

Agents without execution bounds are unsafe for production. Unbounded agents MUST NOT be deployed.


Cost Governance (REQUIRED)

constraints:
  cost:
    maxCostPerDay: ""         # REQUIRED — USD ceiling per agent per day

llm:
  cost_tracking:
    enabled: true             # REQUIRED

Cost MUST be attributable per agent execution. Per-invocation cost emitted as metric. Daily aggregation enforced by ContractPlane.


Messaging Reliability (REQUIRED)

spec:
  messaging:
    reliability:
      deliveryGuarantee: at-least-once   # Default
      retry:
        maxAttempts: 3
        backoff:
          strategy: exponential

Default delivery guarantee is at-least-once. Commands MUST be idempotent unless explicitly declared otherwise.

commands:
  - name: ""
    idempotent: true          # Default — REQUIRED unless documented exception

Failure Model (REQUIRED)

spec:
  failure:
    retryable_errors:
      - timeout
      - rate_limited
      - transient_network
    fatal_errors:
      - policy_deny
      - identity_invalid
      - cost_ceiling_exceeded
      - dragonfly_fail

Fatal errors halt execution immediately. No retry. Escalate to ContractPlane A2H queue.


Integration Surfaces (Exhaustive — No Fifth Category)

Surface Mechanism Bluefly Use Direction
OAuth 2.0 client_credentials + scoped tokens Separate credentials per lane: Governance (read-only), Application (write), CI/CD (deploy) Bidirectional
JSON:API Core + JSON:API Extras Content CRUD (nodes, media, taxonomy, users, menus), component metadata, audit queries Bidirectional
Webhooks Outbound from Source Trigger pipelines on publish/update/delete; ECA receives on governance plane Source → Bluefly
Canvas CLI @drupal-canvas/cli v0.10.0 Component push (React/JSX), page creation, asset library management Bluefly → Source

Security note: Source authorization is scope-driven, not Drupal roles. Governance MUST sit above Source scopes via Cedar + DUADP.

OAuth Lane Architecture

Lane Scopes Purpose
Governance content:read, canvas:read Cedar policy evaluation context (read-only)
Application content:write, canvas:push, media:write Agent-driven content and component operations
CI/CD canvas:asset_library, canvas:js_component Pipeline-driven component deployment

Secrets in Drupal Key module (governance plane). CI/CD secrets as GitLab CI variables (masked, protected). No secrets in code or OSSA manifests.


ContextControl.ai Integration with Source

Primary product for Acquia Source. Constrained reasoning services running inside Source use ContextControl.ai as their shared memory layer.

How It Works

  1. Source agent executes → produces context (content decisions, component metadata, user preferences, compliance state)
  2. Agent calls ContextControl.ai API → POST api.contextcontrol.ai/context with ai_context entity payload
  3. Cedar policy evaluates → permission check (per-site, per-account, per-agent)
  4. Context stored → Postgres + pgvector for semantic retrieval
  5. Other agents query → GET api.contextcontrol.ai/context?scope=site|account|global with Cedar-gated access
  6. Cross-site federation → agents on Site A can access context from Site B if Cedar permits

Permission Model

Scope Description Cedar Policy
Per-site Context visible only to agents on the same Source site site_id == resource.site_id
Per-account Context shared across all sites in the same Acquia account account_id == resource.account_id
Per-agent Context restricted to the specific agent that created it agent_gaid == resource.creator_gaid
Cross-account Context shared between separate Acquia accounts (enterprise) Explicit Cedar permit with bilateral approval
Global Platform-wide context (rare — compliance templates, shared vocabularies) Platform admin only

What Source Agents Get

  • Persistent memory across sessions — chat agents remember previous interactions
  • Cross-site awareness — deployed agents know what happened on other sites in the fleet
  • Compliance context — agents inherit compliance requirements from the account's Cedar policies
  • Semantic search — retrieve context by meaning, not just key-value lookup
  • Audit trail — every context read/write is logged with GAID provenance and cost attribution

API Surface (Fastify + Postgres + pgvector)

POST   /context              — Create context item (Cedar-gated)
GET    /context/:id          — Read context item (Cedar-gated)
GET    /context?scope=...    — Query context by scope (Cedar-gated)
PUT    /context/:id          — Update context item (Cedar-gated)
DELETE /context/:id          — Soft-delete with audit record (Cedar-gated)
POST   /context/search       — Semantic search via pgvector (Cedar-gated)
GET    /context/federation   — Cross-site context federation endpoint

All endpoints emit trace spans. All writes are idempotent (upsert by GAID + content hash).


Canvas Page Migration Pipeline

Second product for Acquia Source: take any URL and migrate its content into a Source site as Canvas components.

Pipeline Flow

1. Input URL → Headless browser scrape (Playwright)
2. Extract content + structure → semantic HTML parsing
3. Map to Canvas component schemas → Bluefly component library
4. Cedar policy check → accessibility (WCAG), brand compliance, content governance
5. Validated components → canvas push to Source site via CLI
6. Audit record → GAID provenance + migration evidence + cost attribution

Component Mapping

Source Content Canvas Component Validation
Hero/banner sections bluefly-hero Image alt text, heading hierarchy, contrast ratio
Navigation bluefly-nav ARIA landmarks, keyboard navigation
Content blocks bluefly-content-section Semantic HTML, reading level
Media galleries bluefly-media-grid Alt text, lazy loading, responsive
Forms bluefly-form Label association, error states, ARIA
Footers bluefly-footer Link integrity, legal compliance

Key Technical Decisions

  • Components use drupal-attribute for Drupal integration
  • All components are React/JSX + Tailwind (Source-native)
  • Component prop descriptions ARE the AI instructions (Source's "Configuration IS the Prompting layer")
  • Single component library shared across multiple Source sites
  • Migration produces a manifest linking source URL → component mapping → Cedar policy result

Surface Compliance Matrix

Every integration maps to exactly one allowed surface. Unmapped integrations are invalid.

Integration Surface Cedar Gate Status
Content publish event (Source → Bluefly) Webhook Yes Active
Content read (Bluefly → Source) JSON:API Yes Active
Content write (Bluefly → Source) JSON:API Yes Active
Canvas component push Canvas CLI Yes Active
OAuth token acquisition OAuth 2.0 No (pre-auth) Active
MCP tool discovery (WebFinger) JSON:API Yes Active
MCP canvas scaffold call Canvas CLI Yes Active
Local DDEV equivalence testing JSON:API No (test env) Active
Context write (agent → ContextControl) External API Yes Active
Context read (agent → ContextControl) External API Yes Active
Page migration (URL → Source) Canvas CLI Yes New

Prohibited Patterns (Kill on Sight)

  1. Custom PHP webhook controller inside source_connect competing with ECA
  2. Ad-hoc HTTP orchestration endpoints (new routes not backed by ECA + contrib)
  3. One-off agent runners outside OSSA / ai_agents_ossa
  4. Duplicate webhook controllers inside source_connect
  5. Any custom code running inside Acquia Source tenant

Contrib Audit Gate

Before any custom PHP, audit contrib + config in this order:

# Check Module Required
1 ECA as sole on-platform orchestration drupal/eca Yes
2 Webhooks module for webhook handling drupal/webhooks Yes (if webhook surface used)
3 JSON:API core + Extras for REST surface drupal/jsonapi_extras Yes (if JSON:API surface used)
4 Secret management & auth keys drupal/key Yes
5 MCP Client for remote HTTP MCP servers drupal/mcp_client (Note: drupal/mcp_client is the single authorized MCP package; earlier references to drupal/mcp are historical and refer to the same capability) Yes
6 Tool API for agent tool exposure drupal/tool Yes

Stop rule: Any *.php file that isn't a plugin implementing an existing contrib API → pipeline FAIL → escalate with proof contrib cannot satisfy the requirement.

CI enforcement: Gate runs in validate stage. allow_failure: false. Output artifact: reports/contrib_audit_gate.yaml.


Flow Contract Template

Every flow touching Acquia Source must declare:

  1. Surface: Which of the 4 allowed surfaces (oauth, json_api, webhook, canvas_cli)
  2. ECA trigger: Config name, event plugin, condition, action chain
  3. Cedar policy: Policy file, principal, action, resource, permit/deny default
  4. Governance plane interaction: Endpoint, type (read/write/evaluate/audit), payload
  5. Contrib audit result: PASS/FAIL per check, escalation ticket if custom PHP required
  6. Pilot readiness: Denver → Pilot path must be direct_scale, not requires_redesign

What's Built vs. What's Needed

Built (Production-Ready)

Component Package Notes
Acquia Source integration & governance layer source_connect Unifies mcp_client, tool, and key for remote tools
Canvas blocks (4 block plugins) agentic-canvas-blocks Dashboard, health, command palette
Canvas component factory source-templates Validate → build → publish pipeline
Cedar policy library cedar-policies repo 229+ rules
OSSA spec + CLI ossa repo Active
DUADP discovery duadp repo Stabilized 2026-04-09
Execution gateway agent-platform Running at api.copaw.us:3050
ContractPlane UI contractplane.ai Running at contractplane.ai:3000
GitLab CI components gitlab_components Public, MIT

Needs Completion

Component Gap Priority
ContextControl.ai API Fastify service with Cedar-gated CRUD + pgvector search P0 — core product for Source
Canvas page migration tool Playwright scraper + component mapper + Cedar gate P0 — second product for Source
Dragonfly COMPLIANCE_ENGINE_URL fix, suspended process P1
Per-domain compliance engines 7 of 8 Cedar PDP containers need deployment P1
kb_cache cross-session persistence 85% built, missing persistence layer P2
blueflyio/compliance-cli Docker image CI pipeline Cedar evaluation P2
blueflyio/canvas-cli Docker image Governed Canvas push P2
Compliance report generator Colorado AI Act / EU AI Act / NIST AI RMF exports P2

Regulatory Deadlines

  • Colorado AI Act — June 2026: Audit evidence export + GAID provenance must be operational
  • EU AI Act — August 2026: OSSA manifest classification + prohibited use enforcement

Hybrid Estate Support

Many Acquia customers run Source + traditional Drupal. One governance standard across both.

Estate Integration Package
Acquia Source OAuth + JSON:API + Canvas CLI + Webhooks (external) source_connect
Acquia Cloud (traditional) Direct Drupal module installation ai_agents, ai_agents_ossa, cedar_policy, mcp_client, tool, key
Site Factory Modules per factory + DUADP cross-site discovery Same as Cloud + duadp
Self-hosted Drupal Modules + DUADP node Full module suite

OSSA manifests are the portable unit. Agent defined for Source → importable to traditional Drupal via ai_agents_ossa Drush, and vice versa. Cedar policies shared via cedar-policies repo.


bluefly/source_connect Extension Architecture

bluefly/source_connect
├── source_connector (Core)
│   ├── SourceConnection (Config Entity)
│   ├── AcquiaSourceCapabilityDiscovery
│   ├── SourcePolicyEvaluator / Governance Profiles
│   └── Drush CLI (source-connect:list, capabilities, doctor)
├── source_connector_acquia (Acquia Platform)
│   ├── Source CMS Profile & Acquia Cloud API v2
│   └── Canvas Semantics
├── source_connector_compliance (Governance)
│   └── Cedar Bridge, Policy Evaluation & Evidence
└── source_connector_mcp (MCP Integration)
    └── Provisioner & Adapter around drupal/mcp_client

Core Architecture Invariant

REUSE THE OWNER. FIX THE OWNER. EXTEND THE OWNER. DO NOT DUPLICATE THE OWNER. - CUSTOM_MCP_PROTOCOL_CLIENT = NO (delegated to drupal/mcp_client) - CUSTOM_JSON_RPC_IMPLEMENTATION = NO (delegated to drupal/mcp_client) - CUSTOM_MCP_TOOL_DERIVER = NO (delegated to drupal/mcp_client)

bluefly/source_connect owns connection profiling, Key-backed OAuth credentials, capability normalization, Cedar policy boundaries, and higher-level compound Tool API operations.

<!-- BLUEFLY-DOC-GOVERNANCE This is a governed Bluefly document.