Skip to content

Alistigo Artifact Pattern

Every Alistigo artifact implements this CALM pattern, defined in packages/architecture/patterns/alistigo-artifact.pattern.json and validated in CI.

Fixed nodes (the same in every artifact) are shown in blue. Variable nodes (filled in per artifact) are shown in orange.

%%{init: {"flowchart": {"htmlLabels": false}}}%%
flowchart TB
classDef boundary fill:#e1e4f0,stroke:#204485,stroke-dasharray: 5 4,stroke-width:1px,color:#000000;
classDef fixed fill:#eef1ff,stroke:#007dff,stroke-width:1px,color:#000000;
classDef variable fill:#fff3e0,stroke:#b85c00,stroke-width:1.5px,color:#000000;

  subgraph npm-cdn["npm CDN"]
  direction TB
      artifact-skill["<artifact>-skill"]:::variable
          subgraph alistigo-artifact["<artifact>"]
          direction TB
              claude-storage-plugin["Claude Storage Plugin"]:::fixed
              document-layer["Document Layer"]:::variable
              domain-layer["Domain Layer"]:::variable
              local-storage-plugin["Local Storage Plugin"]:::fixed
              platform-layer["Platform Layer"]:::fixed
              plugin-bus["Plugin Event Bus"]:::fixed
              presentation-layer["Presentation Layer"]:::variable
              user-plugin["User Plugin"]:::fixed
          end
          class alistigo-artifact boundary
  end
  class npm-cdn boundary

  artifact-host["Artifact Host"]:::fixed
  user["User"]:::fixed

  presentation-layer -->|"Dispatches commands via ApplicationService, reads projections from"| document-layer
  document-layer -->|"Applies commands to aggregates, builds projections from"| domain-layer
  document-layer -->|"Uses plugin contracts and lifecycle hooks from"| platform-layer
  presentation-layer -->|"Uses shared UI components from"| platform-layer
  document-layer -->|"Routes storage operations through"| plugin-bus
  plugin-bus -->|"First-choice storage — when window.claude is present"| claude-storage-plugin
  plugin-bus -->|"Fallback storage — dev / playground / draft mode"| local-storage-plugin
  plugin-bus -->|"User identity lifecycle hooks"| user-plugin
  artifact-host -->|"Embeds in iframe, injects config, brokers storage and AI APIs for"| alistigo-artifact
  alistigo-artifact -->|"Bundle fetched at load time, plugins imported at runtime from"| npm-cdn
  artifact-skill -->|"Agent capability contract for"| alistigo-artifact
  user -->|"Interacts with"| alistigo-artifact
NodeFixed / VariableRationale
UserFixedSame actor in every artifact
Artifact HostFixedSame iframe host contract
npm CDNFixedSame jsDelivr delivery mechanism
Platform LayerFixedShared across all artifacts unchanged
Plugin Event BusFixedSame createPluginBus() in every artifact
Claude Storage PluginFixedSame window.storage wrapper everywhere
Local Storage PluginFixedSame localStorage fallback everywhere
User PluginFixedSame identity/attribution plugin everywhere
<artifact>VariableArtifact-specific name, npm package, description
Domain LayerVariableArtifact-specific aggregates, events, value objects
Document LayerVariableArtifact-specific serialiser and application service
Presentation LayerVariableArtifact-specific React component tree
Artifact SkillVariableArtifact-specific Claude agent skill package

Each artifact extends the base pattern with artifact-specific feature plugins (e.g. list-checkbox-plugin for the list artifact). Feature plugins are connected to the artifact through the plugin bus — they are not part of the structural skeleton captured here, but appear in the concrete implementation architecture.

ArtifactCALM ArchitecturePattern conformance
List Artifactpackages/list-domain/artifact-list.arch.jsonValidated in CI (calm validate -p … -a …)