Socotra
Architecture

How Socotra works

A unidirectional pipeline of small, single-responsibility .NET projects.


Overview

Socotra is a collection of independent .NET projects composed into a single CLI. Each project has one job and depends only on projects "to its left" in the pipeline. Data flows through the Result<T> monad — success or explicit error.

Pipeline diagram

socotra.yamlDesiredParserParseStateReaderScan FSDiffEngineDetect driftPlanEngineOrder stepsExecutorApply

Each box is an independent .NET project. Result<T> flows unidirectionally left → right.

Stage responsibilities

StageInputOutputResponsibility
Parsersocotra.yamlTyped modelDeserialize YAML, surface schema errors
StateReaderFilesystemActual-state modelScan .sln, .csproj, packages, template files
DiffEngineDesired + ActualUnordered change setCompute drift; classify add/modify/destroy
PlanEngineChange setOrdered planTopological sort; assign risk levels
ExecutorPlanResultRun dotnet commands; atomic writes; rollback on failure

Template subsystem

The template subsystem (Socotra.TemplateRegistry) is a parallel pipeline used by ApplyTemplate steps:

TemplateSourceParser → TemplateResolver → TemplateFetcherDispatcher
        → BuiltIn / GitHub / LocalPath Fetcher
        → LocalRegistryStore
        → NamespaceDetector
        → TemplateApplier
        → NormalizedFileWriter (atomic .tmp write + guard header)

Principles

  • Single responsibility per project — no "manager" or "service" grab-bags.
  • No circular dependencies — stages strictly depend left-to-right.
  • Explicit errors via Result<T>; exceptions don't cross boundaries.
  • Atomic writes via .tmp intermediate files.
  • Pure plan — no I/O during plan computation beyond reading state.
Schema 1.1 · CLI 1.0