Runtime Capability Authority ADR: Open Standard for Secure Agents (ai_agents_ossa)¶
1. Capability Inventory¶
Governance must always begin with the capability inventory. Separate the Protocol/Standard from the Implementation.
Capability A: OSSA Specification (Protocol)¶
- Protocol: OSSA (Open Standard for Secure Agents) v0.5.1
- Purpose: The definitive schema and specification defining AI agent manifests, tools, capabilities, access tiers, and transport mechanisms.
- Protocol Authority: Bluefly Product / Open Standard (NPM Project:
openstandardagents)
Capability B: Drupal OSSA Implementation¶
- Implementation: Drupal Contrib module (
ai_agents_ossa) - Purpose: Merely one reference implementation enabling Drupal to consume, validate, and execute OSSA manifests.
- Implementation Authority: Drupal Contrib (Must act strictly as an adapter/bridge to the standard, without reinventing validation logic if possible).
2. Authority Evaluation Order¶
Evaluate authorities in order, then record the stopping point.
Order of Evaluation: Business Capability → Open Standards → Existing Protocols → Drupal Core → Drupal CMS → Drupal Contrib → Composer Ecosystem → NPM Ecosystem → OSSA → Bluefly Extension → Bluefly Product
Stopped at: NPM Ecosystem (blueflyio/ossa/openstandardagents.org)
Reason: The overarching authority for the schema and validation logic belongs to the standalone NPM project. Drupal should not reinvent the schema enforcement; it should bridge the schema into Drupal primitives.
3. Capability Comparison Matrix¶
Split "uses" from "owns". A capability using a core API does not own it.
| Feature / Capability | Current Implementation | Candidate Ecosystem Primitive | Owner | Gap (Delta Taxonomy) |
|---|---|---|---|---|
| Manifest Schema Validation | Custom PHP Validator | NPM OpenStandardAgents | Bluefly Product | PRODUCT (Align with NPM) |
| Identity & Access Tiering | Custom PHP | NPM OpenStandardAgents | Bluefly Product | PRODUCT (Align with NPM) |
| Registry Storage/Catalog | Custom UI / Controllers | Views | Drupal Core | CONFIG (Migrate to Core) |
| Manifest Transport/Expose | Custom Controllers | JSON:API | Drupal Core | CONFIG (Migrate to Core) |
| Tool Binding | Custom Mapping | Tool API (drupal/tool) |
Drupal Contrib | EXTENSION (Extend Contrib) |
| Async Execution | Symfony Messenger | Symfony Messenger / ECA | Symfony/Core | NONE (Uses existing) |
| Entity Data Model | ossa_agent node type |
Config Entities / Nodes | Drupal Core | NONE (Uses existing) |
4. Current Assessment¶
- Protocol Authority: OSSA Specification (OpenStandardAgents NPM package)
- Reference Implementation: Drupal (Contrib Adapter)
- Other Planned Implementations: SDKs, TypeScript Runtimes, OpenClaw
- Confidence: HIGH
- Reason: By acknowledging that the schema authority lives in NPM, we recognize that the Drupal module is just an orchestration bridge. The Drupal specific PHP code should be drastically reduced by leaning on Views for the catalog, JSON:API for manifest transport, and letting the NPM project own the core mathematical schema.
5. Enhancement Backlog (The Engineering Plan)¶
What ultimately reduces custom code.
Move to Core / Config (NONE / CONFIG) * Catalog UI (Rebuild as Views) * Agent Data Storage (Adopt standard Config Entities or Nodes) * Manifest exposure (Rebuild as JSON:API endpoints) * Async execution (Continue using standard Messenger/Queue)
Move to Contrib (EXTENSION) * Tool API plugin bindings * ECA workflow integration points * AI Provider integrations
Retain as Product / Upstream NPM (PRODUCT) * Manifest validation algorithms * Schema definitions * Security tier mapping logic (Note: These should ideally be consumed from or strictly aligned with the NPM standard, avoiding PHP reinvention).
6. Governance Outcome & Evidence Gates¶
Target Outcome: Candidate Upstream (NPM) / Candidate Package (Drupal Contrib)
Evidence Checklist: - [x] Capability inventoried (Protocol vs Implementation separated) - [x] Authority identified (NPM OpenStandardAgents Package) - [x] Remaining delta defined granularly - [ ] Enhancement plan drafted (Focus on replacing custom Catalog/Transport with Views/JSON:API and deferring schema logic to NPM) - [ ] Implementation validated - [ ] Receipt
7. Service / submodule disposition audit (2026-09-08)¶
Binding direction (Thomas, 2026-09-08): ai_agents_ossa is a thin Drupal adapter between drupal/ai_agents (agent framework) and @bluefly/openstandardagents (canonical OSSA schema/contract package). Bluefly custom code is extension / integration / enhancement, never a reimplementation of existing core, contrib, or Drupal AI capability. Target: DUPLICATED_UPSTREAM_CAPABILITY=0, not CUSTOM_CODE=0. Legitimate scope: OSSA ↔ ai_agents integration, OSSA metadata/validation, OSSA plugins/adapters, OSSA governance integration, OSSA discovery where Drupal needs it. Never another agent runtime, tool-calling framework, workflow engine, context store, provider abstraction, or schema authority.
Measured at release/v0.1.x 8e6390d: 240 PHP files, 42,665 lines, 20 tests, 17 submodules. Dispositions: KEEP_AS_EXTENSION, REPLACE_WITH_CORE, REPLACE_WITH_CONTRIB, REPLACE_WITH_CONFIG, REPLACE_WITH_RECIPE, CONTRIBUTE_UPSTREAM, DELETE_DUPLICATE; NOT_ESTABLISHED where evidence is incomplete.
Main module services and plugins¶
| CLASS_OR_SERVICE (lines) | CAPABILITY | EXISTING_UPSTREAM_OWNER | WHY_EXTENSION_NEEDED | DISPOSITION |
|---|---|---|---|---|
Plugin/AiAgent (1), AgentResolver, OssaPromptSubscriber |
OSSA agent exposed as an ai_agents agent; prompt integration | drupal/ai_agents, drupal/ai events | this is the adapter | KEEP_AS_EXTENSION |
ManifestImporter, ManifestExporter, OssaFieldMapper |
OSSA manifest ↔ ossa_agent config entity |
Config Entity API (storage) | Drupal-specific mapping | KEEP_AS_EXTENSION |
DrupalManifestRegistry, ManifestRegistry, ManifestRegistryInterface |
registry over config entities | Entity API queries | thin loader only; two registries exist | KEEP_AS_EXTENSION, consolidate to one |
ToolApiBridge, CapabilityMapper |
OSSA capability ↔ Tool API plugin ids | drupal/tool plugin manager | integration | KEEP_AS_EXTENSION |
Plugin/tool (9), Plugin/AiContextScope (1) |
OSSA operations as tools; context scope | drupal/tool, drupal/ai_context | integration | KEEP_AS_EXTENSION (audit each tool against tool_belt) |
SchemaValidatorService (platform submodule) |
JSON Schema validation | justinrainbow/json-schema + @bluefly/openstandardagents (!206) | adapter/resolution only | KEEP_AS_EXTENSION |
PhpManifestValidator (372) |
hand-written manifest validation | JSON Schema validation above | none once !206 lands; keep only Drupal-specific checks | DELETE_DUPLICATE |
ExecutionService (533), ContextSubscriber (171), KbCacheService (245), SelfHealingManager (68) |
governed execution dispatcher, per-request context store, self-healing loops | ai_agents runtime + Tool API (execution, tool calling), ai_context (context), Queue/ECA (retries) | only the OSSA tiering/policy checks are a gap | REPLACE_WITH_CONTRIB; retain a small policy-check extension; SelfHealingManager DELETE_DUPLICATE |
OssaFeatureListStore (570), OssaProgressService (396) |
OSSA harness feature list and session progress | not a Drupal integration (harness concern) | none in Drupal | CONTRIBUTE_UPSTREAM to the OSSA harness package, or DELETE_DUPLICATE |
OssaBridgeClient (574), OssaDeployClient (198), OssaMeshSyncService (119) |
HTTP clients to studio / deploy / mesh | http_client_manager service definitions (already required; ai_agents_ossa.http_services_api config exists) |
discovery adapter only | REPLACE_WITH_CONFIG; keep a thin discovery adapter |
AgentUserMirror (257) |
agents as Drupal user service accounts | User entity + roles | governance identity | KEEP_AS_EXTENSION (gap NOT_ESTABLISHED) |
LangfuseTracer (212) |
tracing to Langfuse | drupal/ai logging; contrib tracing integrations | none if contrib covers it | REPLACE_WITH_CONTRIB (NOT_ESTABLISHED which contrib tracing module) |
FeatureManager (222) |
feature flags for optional integrations | moduleHandler->moduleExists() + config |
none | REPLACE_WITH_CORE |
DuadpExportService (302), DuadpValidationService (141) |
DUADP export/validation | drupal/duadp (contrib-ready) | none | CONTRIBUTE_UPSTREAM to duadp |
CanvasSyncer (127) |
GitLab OSSA agents → Canvas | Canvas API; ai_agents_ossa_canvas submodule |
overlaps the ai_agents_ossa_canvas submodule |
NOT_ESTABLISHED |
Submodules¶
| SUBMODULE (lines) | CAPABILITY | EXISTING_UPSTREAM_OWNER | DISPOSITION |
|---|---|---|---|
ai_agents_dashboard + _agents + _monitoring (12,169 aggregate; individual counts not broken out) |
dashboards, CRUD, monitoring, heartbeat, charts, Agent Studio sync | Views, JSON:API, Charts, drupal/ai_dashboard (§3 already: Custom UI → Views, Custom Controllers → JSON:API) | REPLACE_WITH_CONFIG / REPLACE_WITH_CONTRIB; product-specific parts belong to the product site |
ai_agents_tunnel (2,237) |
a Cloudflare Tunnel per agent | infrastructure, outside Drupal (IaC owner) | DELETE_DUPLICATE (move out of Drupal) |
ai_agents_ossa_wizard (2,302) |
builder UI + REST API | Form API; JSON:API for the API surface | REPLACE_WITH_CORE for the API; UI NOT_ESTABLISHED |
ai_agents_ossa_platform |
"core foundation, schemas, interfaces" | the main module | DELETE_DUPLICATE (merge into main; keep SchemaValidatorService) |
ai_agents_ossa_eca (2,720), _flowdrop (1,819), _modeler, _context, _chat (931), _api_normalization (1,514), _sandbox |
integrations via those modules' plugin types | ECA, FlowDrop, Modeler API, ai_context, drupal/ai chat, api_normalization | KEEP_AS_EXTENSION (verify thinness; counted modules eca/flowdrop/chat/api_normalization are large for adapters; _modeler, _context, _sandbox individual sizes not listed) |
ai_agents_ossa_canvas (2,574) |
Canvas page building for agent management | Canvas + SDC | KEEP_AS_EXTENSION only if plugin-level; NOT_ESTABLISHED |
ai_agent_ossa_ui_components |
SDC components | theme / Canvas layer | NOT_ESTABLISHED (likely belongs in a theme) |
agent_registry_consumer |
mesh discovery fetch/install | http_client_manager config + discovery adapter | REPLACE_WITH_CONFIG |
ai_agents_ossa_token_efficiency |
uninstall shim | none | DELETE after one release cycle |
Pre-merge inspection of !205 and !206¶
- !205 (7 files, +6/−5): removes
kb_cache,mcp_registry,contextual_memory_orchestratorhard dependencies. The context store (ai_agents_ossa.kb_cache) was already module-local onentity_type.manager+keyvalueand never injected a kb_cache service; no new abstraction is introduced and no behaviour is dropped (one config read moves toai_agents_ossa.settings). Criterion met. The execution/context cluster itself remains an overlap per the table above; that is a separate follow-up, not a reason to hold !205. - !206 (3 files, +93/−5):
package.jsondependency, README note, and an additive resolver inSchemaValidatorService(+84 lines: constants,resolveSchemaPath(),npmPackageRoots()); validation logic unchanged. Only schema-consumption glue. Criterion met. Caveat:schemas/stays as a fallback until consumers runnpm ci; prune it afterwards so no fork of the standard survives.