IMPLEMENTATION GUIDES 13 MIN READ 2026.03.03

> Building an ECM Protocol-Compliant Context Store

Step-by-step guide to implementing an ECM Protocol-compliant context store with full API compatibility.

Building an ECM Protocol-Compliant Context Store

Context Store Requirements

ECM Protocol-compliant context stores must implement the store interface specification. This guide covers building a compliant store implementation.

Storage Backend

Interface Implementation

class ECMContextStore implements ContextStore {
  constructor(private backend: StorageBackend) {}
  
  async put(context: Context): Promise<ContextRef> {
    this.validate(context);
    const ref = await this.backend.insert(context);
    await this.emit('context.created', context, ref);
    return ref;
  }
  
  async get(id: ContextId): Promise<Context | null> {
    return await this.backend.findById(id);
  }
  
  async update(id: ContextId, context: Context, etag?: string): Promise<ContextRef> {
    const existing = await this.backend.findById(id);
    if (!existing) throw new NotFoundError(id);
    if (etag && existing.etag !== etag) throw new ConcurrencyError();
    
    const ref = await this.backend.update(id, context);
    await this.emit('context.updated', context, ref);
    return ref;
  }
}

Query Implementation

ECM-QL Parser

class QueryParser {
  parse(ecmQuery: ECMQuery): BackendQuery {
    const filters = this.parseFilters(ecmQuery.filter);
    const projection = this.parseProjection(ecmQuery.projection);
    const sort = this.parseSort(ecmQuery.sort);
    
    return {
      filters,
      projection,
      sort,
      limit: ecmQuery.limit || 100,
      offset: ecmQuery.offset || 0
    };
  }
  
  private parseFilters(filter: FilterExpression): BackendFilter {
    if (filter.and) {
      return { $and: filter.and.map(f => this.parseFilters(f)) };
    }
    return this.parseSimpleFilter(filter);
  }
}

Concurrency Control

Version Tracking

class VersionedStore {
  async update(id: string, context: Context, expectedVersion?: number): Promise<ContextRef> {
    return await this.backend.transaction(async (tx) => {
      const current = await tx.findById(id);
      
      if (expectedVersion && current.version !== expectedVersion) {
        throw new ConcurrencyError(\`Expected version \${expectedVersion}, found \${current.version}\`);
      }
      
      const newVersion = current.version + 1;
      await tx.update(id, {...context, version: newVersion});
      
      return {
        id,
        version: newVersion,
        etag: this.computeEtag(context, newVersion)
      };
    });
  }
}

Event Emission

Event Publisher

class EventPublisher {
  constructor(private transport: EventTransport) {}
  
  async publish(event: ContextEvent): Promise<void> {
    const envelope = {
      event_id: generateUUID(),
      event_type: event.type,
      timestamp: new Date().toISOString(),
      payload: event.data
    };
    
    await this.transport.publish(event.type, envelope);
  }
}

Indexing Strategy

Index Configuration

const indexConfig = {
  primary: { field: 'id', unique: true },
  secondary: [
    { fields: ['context_type', 'created_at'], name: 'type_created' },
    { fields: ['metadata.tenant_id'], name: 'tenant' }
  ],
  text: { fields: ['data.*'], name: 'content_search' },
  vector: { field: 'embedding', dimensions: 1536, metric: 'cosine' }
};

Compliance Testing

Verify compliance with test suite:

  • CRUD operations: All basic operations work
  • Query support: ECM-QL queries execute correctly
  • Concurrency: ETag/version conflicts detected
  • Events: Change events emitted
  • Error codes: Correct error responses

Conclusion

Building a compliant context store requires attention to interface contracts, query parsing, concurrency control, and event emission. Use the compliance test suite to verify implementation correctness.

//TAGS

STORE IMPLEMENTATION BACKEND PROTOCOL