CRUMB a card from devarno-cloud

Engine Subsystems Map

sparki intermediate 6 min read

ELI5

The engine is a kitchen with named stations: scan is the prep cook who identifies ingredients (languages, frameworks), score is the food critic, loco is the delivery driver, forgery is the pastry station that generates contracts, and bind/link are the chefs who tie requirements and tools together. Each station has its own drawer (package) and recipe card (types.go).

Technical Deep Dive

Subsystems live under services/api-engine/subsystems/. Each is a self-contained Go package with types.go, a top-level entry file, and supporting modules. Subsystems are stateless wrappers around their domain types; persistence flows through internal/repository.

Subsystem Catalogue

SubsystemPurposeHeadline Types
bindRequirements traceability — links requirements ↔ tests ↔ codeRequirement, TraceLink, TraceabilityMatrix
linkCLI tool detection and install orchestrationTool, ToolInfo, InstallMethod
locoEngine-side deployment client to deploy-locoDeploymentConfig, DeploymentStrategy, HealthCheck*
scanProject detection — language, framework, package manager, build toolLanguage, Framework, PackageManager, BuildTool
scoreQuality scoring and metric aggregationMetric, MetricSeries, BuildMetrics, TestMetrics
forgeryContract / catalogue generation from sourcesProtocolType, SourceType, CatalogueType, ForgeStatus
runBuild/test runner registry, coverage collectionRunner, coverage helpers
diagnoseHealth probes and self-diagnosis(under subsystems/diagnose)
integrationThird-party integration glue
runimplRunner implementations

Wiring

flowchart TD
API[REST handlers internal/api] --> CORE[internal/core]
CORE --> SCAN[scan]
CORE --> RUN[run]
CORE --> SCORE[score]
CORE --> FORG[forgery]
CORE --> BIND[bind]
CORE --> LINK[link]
CORE --> LOCOS[loco subsystem client]
RUN --> EXEC[internal/executor BuildExecutor]
EXEC --> WORKERS[Worker pool]
WORKERS --> DOCKER[docker.go]
CORE --> REPO[internal/repository postgres]
EXEC --> MQ[internal/mq Producer]
LOCOS -->|REST + queue| LOCO_SVC[deploy-loco service]

run vs internal/executor

The run subsystem is the high-level domain (test runners, coverage collection, runner registry). internal/executor is the lower-level worker pool that turns a BuildJob into shell + Docker invocations (worker.go, docker.go, queue.go). run calls down to executor; executor does not call up.

Key Terms

  • subsystem → a Go package under subsystems/ owning one domain
  • types.go → canonical type/enum file every subsystem ships with
  • registry → in-memory lookup (e.g., run.Registry for runners) populated at startup
  • forgery → contract/catalogue generator; not to be confused with services/build-forgery placeholder

Q&A

Q: Where is framework detection implemented? A: subsystems/scan — see the Language, Framework, PackageManager, BuildTool enums in subsystems/scan/types.go. Detector logic lives under subsystems/scan/detectors.

Q: Does score depend on bind? A: No. Score consumes BuildMetrics and TestMetrics from the build pipeline; bind is the requirements/traceability subsystem and is a peer.

Q: Why does loco exist twice? A: subsystems/loco is the engine-side client that knows about DeploymentConfig and the loco REST API. The standalone deploy-loco service is the Rust worker. The subsystem’s job is to translate engine requests into deploy-loco API calls.

Examples

A push triggers: scan identifies the project (Go + Fiber + go-mod), run selects a runner, executor runs the build via Docker, score records build/test metrics, forgery regenerates the OpenAPI catalogue, loco subsystem hands off to deploy-loco for the deploy, and bind updates the traceability matrix from the new test results.

neighbors on the map