Skip to content

Build and test Product source

Build and test Product source with immutable resources and one capability folder per Block.

Use this guide when you lay out and test Product source for Workspace. You keep one folder per capability Block, split resources into local modules, and run focused offline checks before publication. Use the exact compatible CLI and CDK packages pinned by the repository.

Before you start

You need an authoring repository from merulan workspace init. The CLI and the repository must use the same @merulan/cdk release. A different installed release refuses with cdk_version_mismatch before any source runs.

Lay out capability folders

Each Product lives in src/products/$PRODUCT_KEY/product.ts. Each Block is a folder beside it, such as src/products/$PRODUCT_KEY/context/block.ts. No blocks wrapper folder is needed. Keep the Block's resources in the same folder, for example in schema.ts.

src/products/example/
  product.ts
  context/
    block.ts
    schema.ts
  review/
    block.ts

A folder name does not select anything. The Block's handles list does. A folder that no Block imports holds drafts that install nothing, and the lint reports it as a warning.

Split and reuse modules

Resources may sit in block.ts, in one schema.ts, or in several modules behind a local re-export. Each layout compiles to the same Product with the same digest. A second Block that needs a resource imports its handle from the owning folder. Reuse across Products goes through an exact Product reference, not a shared folder.

product.ts selects Blocks through product(...).addBlock(...) and owns its configuration, requirements and APQC mappings through configure, requires and mapTo. Export composed = definition.synthesize() and product = composed.source so the CLI can compare selected resource ownership with the compiled source. The native manifest is output; do not replace these operations with a manifest-shaped wrapper.

Test the source

Run the offline checks in this order after each change.

  1. Run merulan workspace lint --dir .. The result lists diagnostics with file and line.
  2. Run merulan product build --source src/products/$PRODUCT_KEY/product.ts. The result names the draft file and its contentDigest.
  3. Run merulan product source-inventory --source src/products/$PRODUCT_KEY/product.ts --offline. The result lists the Entities, relationships, and the owner of each resource.

None of these commands contacts a Merulan service or changes a Workspace. A test in your repository can import product.ts and call compileProduct on its product export to check a draft in memory. Use one test worker for the focused file while iterating. Test immutable reuse, wrong-owner refusal and restoration of a broken reference; compare native output when moving files or migrating syntax. Package/CLI and installed-reader tests provide separate evidence beyond this fast source loop.

Checkpoints

The lint is clean, the build digest is stable across layouts, and every resource has one owner. Regenerating with merulan product init and the same inputs reports each file as unchanged.

Success

The Product compiles to a draft with the digest you expect. Moving modules between folders does not change that digest. The inventory matches what the registered products.source.inventory operation returns for the same draft.

When it fails

Each refusal names the file and line to repair.

workspace.structure.cdk_version_mismatch

The repository resolves a @merulan/cdk release that differs from the CLI's release. Pin the exact compatible release and reinstall. Nothing was run.

workspace.structure.block_misplaced

A Block file sits outside a capability folder of its Product. Move it to src/products/$PRODUCT_KEY/$CAPABILITY/block.ts.

workspace.structure.orphan_resource

A reached module exports a resource that no Block lists. List the handle or remove the export.

Recovery

A failed check changes no file. Fix the reported line and run the same check again. merulan product init refuses to overwrite a changed file, so regeneration cannot erase your work.

Export and delegation

Use Merulan to check Product source when the release must be the same no matter how the repository is arranged. Merulan retains the compiled draft and its digest. The folder layout, tests, and editor stay in your repository. Source counts only after the CDK compiles it. An exported draft carries its resources and owners, not your folders or tests.

Next steps