documentize.cloud

Decision 02

Three products, one catalogue

Cloud, Serverless and Self-Host are separate products with different engines — and the duplication between them has to be governed.

The three products

Different engines, different buyers, one plugin catalogue between them.

Documentize Cloud

hosted · multi-tenant

Workspace, file library, recipes and runs. The pipeline product.

  • DAG orchestrator
  • 49 manifest plugins
  • Resource governor
  • Checkpointed resume

Documentize Serverless

AWS Marketplace · single-tenant

Scale-to-zero document processing inside the customer's own account.

  • Fn control plane
  • 32 auto-discovered workers
  • Per-plugin instances, 0 to N
  • Gigabyte-second cost model

Documentize Self-Host

licensed binary · air-gapped capable

One binary, no external dependencies, entitlement by signed key.

  • Local file storage
  • No broker, no Redis
  • Nothing leaves the network

MCP is not a fourth product — it is a caller, and it ships against Cloud and Self-Host both. That portability is already demonstrated: moving the MCP tool surface from the hosted Kafka path to a local queue changed the dispatch call and nothing else about the 37 tools.

Why two engines, deliberately

This reverses an earlier working assumption, and the reason matters.

The first instinct was to converge: pick the DAG engine for cloud and retire the worker tree plugin by plugin. That is the right call when there is one product. It is the wrong call once Serverless is its own Marketplace SKU, because the worker tree and the Fn control plane are that product — scale-to-zero is its whole proposition, and the DAG engine does not offer it.

So both trees stay. The duplication stops being technical debt and becomes a product boundary — but only if the boundary is drawn on purpose.

Where the boundary belongs

Some layers should be shared and are not. Some are correctly separate.

LayerShould beToday
Document logic
conversion, OCR, page operations
Shared library referenced by both treesduplicated two implementations per operation
Invocation contract
how a unit of work is called
Separate — they genuinely differcorrect
Scheduling
what runs when
Separate — DAG versus scale-to-zero is the product differencecorrect
Parameter schemaOne declaration, both treesone side only declared parameters exist in the plugin tree

Operations including compress, rotate, merge, OCR, parse, split, flatten and resize currently exist as separate implementations on both sides. With two products shipping, every document-processing fix has to be made twice, and the two will drift in output — which is exactly the difference a customer comparing the products would notice.

The rule to adopt before more divergence

New document logic lands in a shared library, and each tree keeps only its invocation wrapper. This should be done opportunistically — whenever an operation is touched for another reason — rather than as a scheduled extraction. The immediate cost is close to zero; the cost of not deciding is two diverging engines a year from now.