Back to Docs
Platform Commitments

Platform Principles

13 non-negotiable truths about EKOM. These are architectural constraints that hold across all accounts, all execution modes, all tenants.

1. Execution engine first

EKOM is an execution engine first, analytics second.

Visibility signals are directional inputs to the enrichment pipeline. They are not the product. No analytics-only feature ships without an enrichment dependency.

  • Enforced By: Feature prioritization gate — no analytics-only feature ships without enrichment dependency.
  • Test Evidence: review_gate_no_analytics_only.spec.ts

2. Patch-only writes

The conversational layer never writes to connectors directly. Every write goes through the Patch system.

The conversational layer creates Jobs and Patches. The engine executes them. No shortcut exists. No code path bypasses this constraint.

  • Enforced By: PatchGate middleware — connector.write() blocked without valid Patch reference. Any chat action without a Patch returns 403.
  • Test Evidence: patchgate_blocks_direct_write.spec.ts

3. Reversible deployments

All changes are reversible. Every deployment is versioned.

Patches are atomic diffs with before/after snapshots. Rollback is always available. Rollback history is retained alongside forward changes.

  • Enforced By: PatchLog + VersionStore — every deploy writes before/after to immutable log. Rollback restores prior field value.
  • Test Evidence: version_store_rollback.spec.ts

4. Policy-first generation

Policies constrain all automation. They are evaluated before patch generation, not after.

Policies define what the system may and may not do. They are user-configurable constraints, not suggestions. If a field is protected, a scope is restricted, or a product is excluded, the system respects that boundary before it begins working.

  • Enforced By: PolicyEvaluator runs before PatchGenerator. A policy-rejected field halts generation — it is not filtered post-hoc.
  • Test Evidence: policy_evaluator_before_generation.spec.ts

5. Synthetic visibility

Visibility is synthetic unless explicitly validated.

V1 visibility uses synthetic queries and snapshot comparisons. Surface rate is a synthetic / directional signal — not ground truth analytics. All metrics are query-set dependent.

  • Enforced By: All visibility metrics carry UI label: "Synthetic / Directional". No metric renders without signal_type = 'synthetic' tag.
  • Test Evidence: visibility_label_synthetic.spec.ts

6. Tenant isolation

Every tenant is isolated. Every request is scoped.

No cross-tenant data access. No cross-catalog reasoning. Tenant ID is present on every object.

  • Enforced By: TenantScope middleware — every DB query includes tenant_id filter. A request without tenant_id returns 403.
  • Test Evidence: tenant_scope_isolation.spec.ts

7. Atomic patches

Patches are atomic and auditable.

Each Patch targets one product, one field. Every Patch has a source, confidence score, and approval record. Compound bulk changes are decomposed into individual, inspectable units.

  • Enforced By: Patch schema validation — rejects multi-field or multi-product payloads. Compound patches fail validation.
  • Test Evidence: patch_schema_rejects_compound.spec.ts

8. Canonical schema spine

The canonical schema is the spine of the system.

Normalizer, detector, patch generator, and scoring engine all operate on the canonical schema. No module bypasses it.

  • Enforced By: Type system — all engine modules accept/return CanonicalProduct type. Raw connector data fails type check.
  • Test Evidence: canonical_type_enforcement.spec.ts

9. Lifecycle enforcement

No feature may bypass the engine lifecycle.

Every change flows through: normalize → detect → propose → approve → deploy → audit. No step is optional. No shortcut exists.

  • Enforced By: LifecycleGuard — state machine enforces step ordering. Deploy without approval returns 403.
  • Test Evidence: lifecycle_guard_order.spec.ts

10. Idempotent deployment

Deployment is idempotent. Applying the same patch twice produces the same result.

Patches use field-level before/after values. Conflict detection prevents stale overwrites. If a deployment is interrupted and retried, your catalog ends up in the correct state — not a corrupted one.

  • Enforced By: ConflictDetector — compares before-value against current. Duplicate patch apply returns no-op, not error.
  • Test Evidence: conflict_detector_idempotent.spec.ts

11. Sandbox by default

Sandbox is the default deployment target. Production writes require explicit escalation.

New deployments target a safe sandbox environment by default. No accidental production mutations.

  • Enforced By: DeployTarget defaults to SANDBOX. Production requires Approval.escalation = true. ConnectorScope = READ_ONLY in V1.
  • Test Evidence: deploy_target_sandbox_default.spec.ts

12. Phase dependencies

No phase ships before its dependencies are complete.

Build sequence is strict: auth → ingestion → normalization → detector → patches → approval → deployment → conversation → visibility.

  • Enforced By: Phase dependency graph — CI blocks merge if dependent phase acceptance tests are not green.
  • Test Evidence: ci_phase_dependency_gate.spec.ts

13. Immutable approvals

Every approval is recorded. Who approved, when, what scope, what policy.

Approval objects are immutable audit records. They are never deleted or modified after creation. Your audit trail is permanent and tamper-proof.

  • Enforced By: Approval table has no UPDATE/DELETE permissions. DELETE on approval record returns 403.
  • Test Evidence: approval_immutable_record.spec.ts
Related