Skip to content

Assembly Behavior in Local vs. Enterprise Editions

The Unified Artifact Assembly (UAA) API, CLI, and web workspace are fully implemented in both SkillMeat editions. This guide covers what's identical, what's edition-specific storage, and how the settings/policy layer works.

Feature rollout: one flag, both editions

UAA is gated behind a single flag, SKILLMEAT_UNIFIED_ARTIFACT_ASSEMBLY_ENABLED (default off), that behaves identically regardless of edition. With the flag off, the entire /api/v1/assemblies/* API, the skillmeat assembly CLI, and the Assembly workspace are unavailable, and every legacy template/composite/bundle/deployment-set path is completely unchanged — this is true whether you're running local or enterprise edition. Set the flag to true to opt in; see Migration & Compatibility for the full rollout model. Everything below in this guide describes behavior once the flag is enabled.

What's identical

  • The full /api/v1/assemblies/* surface — module/preset/rule-set/ assembly CRUD, validate/import/export, and resolve/preview/ apply/lock — is the same contract in both editions. The router itself never branches on edition; every route delegates to one AssemblyService regardless of which edition is running.
  • Authentication — every route requires a normal authenticated request (the same require_auth() dependency every other protected route uses). There is no assembly-specific permission scope beyond being authenticated; access control is the same as any other artifact-management endpoint in your deployment.
  • builtin/user/project TOML-authored definitions are read from the filesystem the same way in both editions — packaged resources, ~/.skillmeat/, and ./.skillmeat/*.toml respectively.
  • The bounded rule/preset/module vocabulary (allowed rule actions, condition operators, declared facts, merge strategies) is identical — it's enforced by the domain schema itself, not by edition-specific code.

What differs: storage backend

managed definitions and materialization records are the one part of UAA that's backed by a database, and the database differs by edition:

Layer Local edition Enterprise edition
Assembly/module/preset/rule-set definitions (managed:* refs) SQLite (~/.skillmeat/cache/cache.db) PostgreSQL, tenant-scoped
Materialization records (apply history / idempotency ledger) SQLite PostgreSQL, tenant-scoped

Dispatch between the two is resolved once, in dependency injection, based on your deployment's configured edition — never inside the router or the service layer. In enterprise, definitions and materialization records get the same tenant isolation as every other tenant-scoped enterprise table; in local (single-tenant) edition there is no tenant column to isolate on.

Practically: if you're on local edition, everything about UAA works with zero additional configuration. If you're on enterprise edition, managed assembly definitions and materialization history are scoped to your tenant the same way your other enterprise-native artifacts are.

Policy settings and precedence

GET /api/v1/settings/assembly (and skillmeat config get assembly.* / skillmeat config set assembly.<key> <value>) resolve one effective settings value from exactly four layers, checked in this order (each layer may only narrow what the layer before it allows — never widen a limit, grow an allow-list, or re-enable a feature a prior layer turned off):

  1. Builtin defaults — the absolute ceiling: feature enabled; all four DefinitionSource values allowed; module-graph depth 12; module count 200; module content size 2 MiB; every declared RuleActionType and target adapter permitted.
  2. Enterprise policy — set via SKILLMEAT_ASSEMBLY_* environment variables (SKILLMEAT_ASSEMBLY_ENABLED, SKILLMEAT_ASSEMBLY_MAX_MODULE_GRAPH_DEPTH, SKILLMEAT_ASSEMBLY_ALLOWED_SOURCE_SCOPES, etc.) — lets an enterprise deployment narrow the feature for every user/project without touching any individual config file. This layer is a no-op if left unset (in local edition it's always unset).
  3. User config — the [assembly] table in ~/.skillmeat/config.toml.
  4. Project config — the [assembly] table in ./.skillmeat/config.toml, discovered by walking up from your current directory for the .skillmeat/manifest.toml sentinel.

A malformed layer, or a layer that tries to widen past its ceiling (e.g. a project config raising max_module_count above what enterprise policy allows), is rejected outright — the resolution is atomic, so a bad layer never gets partially applied.

# Read what's actually in effect for you right now
skillmeat config get assembly.max_module_count

# Narrow it further for you, everywhere (writes the user layer,
# ~/.skillmeat/config.toml — validated against the same effective-settings
# resolver before writing, so a value exceeding the current ceiling is
# rejected up front)
skillmeat config set assembly.max_module_count 50

config get/config set only read/write the user layer. To narrow a setting for one project only, add an [assembly] table directly to that project's ./.skillmeat/config.toml:

[assembly]
max_module_count = 50
allowed_target_adapters = ["claude_skill", "claude_command"]

This settings surface is a policy ceiling that applies once the feature is enabled — it is separate from (and layered on top of) the SKILLMEAT_UNIFIED_ARTIFACT_ASSEMBLY_ENABLED on/off flag covered above. See Migration & Compatibility for the full rollout model.