Skip to content

GenerationRecipeService

Target

This page describes intended behaviour or structure. No implementation is claimed unless a section is explicitly marked Current implementation or Evidence.

Bounded context BC-15 Generation Recipe
Platform / plane Template & Library / Software Factory pack
Deployment granularity module of host · host TemplateCatalogHost
Status target · ConnectSoft.Factory.Templates.Recipes
Built from connectsoft-microservice · libraries: connectsoft-extensions-saas-abstractions, connectsoft-extensions-messaging-model, connectsoft-extensions-persistence-model-nhibernate
Decisions ADR-0021
Traceability FR-03 FR-06 FR-07 FUX-01 FUX-03 NFR-11 NFR-13 XL-03 XL-07 XL-10

Purpose and responsibilities

GenerationRecipeService is the contract between design and generation. A recipe takes a Published blueprint version, proposes a module plan from its context map and domain model (one microservice per context, a gateway, a shell and microfrontends per UI blueprint, libraries per shared kernel, workers, API clients, documentation, pipelines, infrastructure), pins a Published template version with switches and parameters per module and Published library versions for all, and is validated against manifests, switches and the compatibility matrix with evidence. An approved recipe is immutable; a generation run executes it (agents call GetApprovedRecipe), and every module's generated output is recorded — run, attempt, agent release, template version, manifest hash, generated and preserved files with hashes, the change proposal and the merged commit — so a re-scaffold can tell generated from hand-edited content.

It absorbs the June-2026 template-validation and pipeline-generation rows (pipeline definitions are generated outputs). The scaffold engine as a service stays later and optional; SaaS descriptors enter through BlueprintService's import (ADR-0025) and generation follows the recipe path.

Context and boundaries

flowchart LR
    S["GenerationRecipeService"]
    AgentRuntimeWorker["AgentRuntimeWorker"] -->|grpc| S
    StudioBff["StudioBff"] -->|sync-http| S
    S -->|grpc| BlueprintService["BlueprintService"]
    S -->|grpc| TemplateRegistryService["TemplateRegistryService"]
    S -->|grpc| RunControlService["RunControlService"]
    S -->|grpc| ModelRouterService["ModelRouterService"]
    S -->|grpc| ArtifactService["ArtifactService"]
    S -. "RecipeValidated" .-> E_RecipeValidated(("event"))
    S -. "RecipeApproved" .-> E_RecipeApproved(("event"))
    S -. "GenerationCompleted" .-> E_GenerationCompleted(("event"))
    S -. "GeneratedOutputRecorded" .-> E_GeneratedOutputRecorded(("event"))
Hold "Alt" / "Option" to enable pan & zoom

This service never writes code. Generation is a Factory run with the sandbox tools for scaffolding and the propose-change-set tool for the result, under Run Control's gates. A newer template release offers a new recipe version; the fleet's re-scaffold rollout (P12) starts from such a version.

Domain model

GenerationRecipe — The complete, validated instruction set for generating a product or module: blueprint version, template versions per module, library versions, switches and parameters per module, target repository layout, pipeline generation settings, and the compatibility evidence it was validated against. (catalog entry)

Field Type Required Description
recipeId guid yes
tenantId string yes
projectId string yes
version int yes
blueprintId string yes
blueprintVersion string yes
modules json yes module plan: kind, context, template id and version, switches, parameters, path
libraries json yes Library versions pinned for all modules.
repositoryLayout json yes mono-repo or repo per module; branch; pipelines
compatibilityEvidence json yes
state enum:RecipeState yes
approvedBy string no
createdAt datetime yes

Invariants:

  • Every module references a Published template version whose switches accept the module's parameters; every library is Published and Compatible with every template that consumes it, with evidence.
  • A recipe is immutable once Approved; a change is a new version that supersedes it.
  • Generation executes as a Factory run (sandbox class for scaffolding, shared-write for the change proposal); this service never writes code.
stateDiagram-v2
    Draft --> Validated : PlanValidated
    Validated --> Draft : Changed
    Validated --> Approved : Approved
    Approved --> Executing : RunSubmitted
    Executing --> Generated : RunCompleted
    Executing --> Approved : RunFailed
    Approved --> Superseded : NewVersion
    Generated --> Superseded : NewVersion
Hold "Alt" / "Option" to enable pan & zoom

Events: RecipeValidated, RecipeApproved, GenerationCompleted · Tables: GenerationRecipes, ModulePlanEntries · Repository: GenerationRecipeRepository

GeneratedOutput — Provenance of one generated module at one commit: the recipe version, the Factory run and attempt, the agent release, the template version and manifest hash, the files generated and preserved, the pipeline definitions written, and the change proposal that carried it. (catalog entry)

Field Type Required Description
outputId guid yes
tenantId string yes
projectId string yes
recipeId guid yes
recipeVersion int yes
moduleName string yes
runId guid yes
attemptId guid yes
agentReleaseId string yes
templateId string yes
templateVersion string yes
manifestHash string yes
generatedFiles json yes Paths and hashes.
preservedFiles json yes Paths left untouched per the manifest.
proposalId guid no
commit string no
generatedAt datetime yes

Invariants:

  • Generated files are listed with hashes so a re-scaffold can tell generated from hand-edited content; preserved paths are never overwritten.

Events: GeneratedOutputRecorded · Tables: GeneratedOutputs · Repository: GeneratedOutputRepository

erDiagram
    GenerationRecipe {
        guid recipeId PK
        string tenantId
        string projectId
        int version
        string blueprintId
        string blueprintVersion
        json modules
        json libraries
        json repositoryLayout
        json compatibilityEvidence
        enum_RecipeState state
        string approvedBy
        datetime createdAt
    }
    GeneratedOutput {
        guid outputId PK
        string tenantId
        string projectId
        guid recipeId
        int recipeVersion
        string moduleName
        guid runId
        guid attemptId
        string agentReleaseId
        string templateId
        string templateVersion
        string manifestHash
        json generatedFiles
        json preservedFiles
        guid proposalId
        string commit
        datetime generatedAt
    }
    ModulePlanEntry {
        string name

        enum_ModuleKind kind

        string contextId

        string templateId

        string templateVersion

        json switches

        json parameters

        string path

    }
    GenerationRecipe ||--o{ ModulePlanEntry : contains
Hold "Alt" / "Option" to enable pan & zoom

Entities and value objects

ModulePlanEntry (entity, in GenerationRecipe) — One module to generate.

Field Type Required Description
name string yes
kind enum:ModuleKind yes
contextId string no
templateId string yes
templateVersion string yes
switches json yes
parameters json yes
path string yes

Data model and storage

Store Role Engine / profile Tables
Template & Library store primary azure-sql / nhibernate-sqlserver GenerationRecipes, ModulePlanEntries, GeneratedOutputs
Artifact content store blob blob / azure-blob —
Table Owner Columns Indexes
dbo.GenerationRecipes GenerationRecipe 12 1
dbo.ModulePlanEntries ModulePlanEntry 11 0
dbo.GeneratedOutputs GeneratedOutput 17 2

Full DDL: appendix.

APIs

Method Path Operation Scope Side effects Idempotency Gateway Summary
GET /factory/recipes ListRecipes factory.recipes.read read natural GW-03 Recipes of a project with versions and state.
GET /factory/recipes/{recipeId}/versions/{version} GetRecipe factory.recipes.read read natural GW-03 The module plan, pinned versions, switches, parameters, layout and compatibility evidence.
POST /factory/recipes DraftRecipe factory.recipes.write shared-write key-header GW-03 Draft a recipe from a Published blueprint version (the module plan is proposed from the context map; people or agents adjust it).
POST /factory/recipes/{recipeId}/versions/{version}/validate ValidateRecipe factory.recipes.write shared-write natural GW-03 Validate modules against manifests, switches and the compatibility matrix.
POST /factory/recipes/{recipeId}/versions/{version}/approve ApproveRecipe factory.recipes.approve shared-write natural GW-03 Approve a Validated recipe for generation (Requester or Asset maintainer; policy may require a Reviewer).
GET /factory/projects/{projectId}/generated-outputs ListGeneratedOutputs factory.recipes.read read natural GW-03 Provenance of generated modules by commit with generated and preserved files.
gRPC service Method Streaming Visibility Side effects Summary
Recipes GetApprovedRecipe none internal read The approved recipe a generation run executes (agents read it at the start of the run).
Recipes RecordOutput none internal shared-write Record generated-output provenance from a generation attempt.

Messages

Event Topic Scope / v Aggregate Consumers Summary
RecipeValidated generation.recipes.v1.recipe-validated integration / 1 GenerationRecipe StudioBff, AuditService A recipe passed (or failed) validation.
RecipeApproved generation.recipes.v1.recipe-approved integration / 1 GenerationRecipe RunControlService, StudioBff, AuditService A recipe may be executed by a generation run.
GenerationCompleted generation.recipes.v1.generation-completed integration / 1 GenerationRecipe StudioBff, AuditService, DashboardService, FleetRolloutService, RepositoryIntelligenceService The generation run completed and every module's provenance is recorded.
GeneratedOutputRecorded generation.outputs.v1.generated-output-recorded integration / 1 GeneratedOutput RepositoryIntelligenceService, StudioBff, AuditService One module's generated output provenance exists.

RecipeValidated payload:

Field Type Required Description
recipeId guid yes
version int yes
tenantId string yes
projectId string yes
passed bool yes
modules int yes

RecipeApproved payload:

Field Type Required Description
recipeId guid yes
version int yes
tenantId string yes
projectId string yes
approvedBy string yes

GenerationCompleted payload:

Field Type Required Description
recipeId guid yes
version int yes
tenantId string yes
projectId string yes
runId guid yes
modules int yes
proposalIds json yes

GeneratedOutputRecorded payload:

Field Type Required Description
outputId guid yes
tenantId string yes
projectId string yes
moduleName string yes
templateId string yes
templateVersion string yes
runId guid yes
proposalId guid no
Command Handled by Result events Summary
DraftRecipe GenerationRecipe —
ValidateRecipe GenerationRecipe RecipeValidated
ApproveRecipe GenerationRecipe RecipeApproved
Event Producer Handler Purpose
BlueprintPublished BlueprintService OfferRecipe A Published blueprint can be turned into a recipe.
BlueprintValidated BlueprintService InvalidateDrafts A changed blueprint invalidates Draft recipes built on it.
ContextMapDerived BlueprintService ProposeModulePlan The module plan is proposed from the context map.
DomainModelDerived BlueprintService ProposeModulePlan Module parameters from the domain model.
TemplateVersionPublished TemplateRegistryService OfferUpgrade A newer template version offers a recipe version (re-scaffold).
LibraryVersionDiscovered TemplateRegistryService TrackLibraries Library versions available to pin.
CompatibilityChecked TemplateRegistryService RefreshEvidence Compatibility evidence for validation.
RunCompleted RunControlService CompleteGeneration The generation run completed.
RunFailed RunControlService RevertToApproved The generation run failed; the recipe stays Approved.
ChangeProposalMerged PipelineExecutionService LinkCommit Generated outputs link to their merged commit.

Workers and jobs

Worker Trigger Output events Retry Idempotency key Summary
PlanProposer event — fixed blueprintId + blueprintVersion Proposes a module plan from the context map and domain model (one microservice per context, a gateway, a shell and MFEs per UI blueprint, libraries per shared kernel) using Published template versions and the structured profile for naming.
RecipeValidator manual on ValidateRecipe RecipeValidated fixed recipeId + version + hash Validates module entries against manifests and switches and every pinned library against the matrix with evidence.

Actors and grains

None modelled

No grains are modelled for this item yet.

Sagas and long-running flows

None modelled

No sagas are modelled for this item yet.

sequenceDiagram
    participant B as BlueprintService
    participant R as GenerationRecipeService
    participant T as TemplateRegistryService
    participant U as Requester
    participant RC as RunControlService
    participant A as Agent attempt
    B-)R: BlueprintPublished + ContextMapDerived + DomainModelDerived
    R->>R: PlanProposer: modules per context, templates, libraries
    U->>R: adjust, ValidateRecipe
    R->>T: manifests, switches, compatibility evidence
    R-)U: RecipeValidated
    U->>R: ApproveRecipe
    R-)RC: RecipeApproved → generation run submitted
    A->>R: GetApprovedRecipe
    A->>A: scaffold in sandbox, propose-change-set
    A->>R: RecordOutput (files, hashes, template version)
    RC-)R: RunCompleted → GenerationCompleted
Hold "Alt" / "Option" to enable pan & zoom

Options and configuration

Section Key Type Default Reloadable Secret Summary
Templates:Recipes ProposerProfile string structured yes no Model profile for plan proposals.
Templates:Recipes RequireReviewerApproval bool false yes no Require a Reviewer to approve recipes (policy may enforce per project).

Metrics and observability

Metric Instrument Unit Dimensions Summary
connectsoft.factory.recipes counter {recipe} tenant, state Recipes by state.
connectsoft.factory.recipes.generated_modules counter {module} tenant, kind, templateId Modules generated by template.
connectsoft.factory.recipes.validation_failures counter {failure} reason Recipe validation failures by reason.

Security

Authentication client-credentials
Scopes factory.recipes.read (Read recipes and provenance.); factory.recipes.write (Draft and validate (Requester, Asset maintainer, agents under a run).); factory.recipes.approve (Approve (Requester or Reviewer per policy).)
Roles Requester, Reviewer, AssetMaintainer, PlatformAdmin, Observer
Tenant isolation row-filter
Data classification confidential
Max side-effect class shared-write
Secrets —

Dependencies

Outbound

Target Kind Purpose Failure mode Required
BlueprintService grpc Derived models. fail-fast yes
TemplateRegistryService grpc Manifests and compatibility. fail-fast yes
RunControlService grpc Generation runs. fail-fast yes
ModelRouterService grpc Plan proposals through the structured profile. degrade no
ArtifactService grpc Recipe documents and provenance artifacts. fail-fast yes

Inbound

Target Kind Purpose Failure mode Required
AgentRuntimeWorker grpc GetApprovedRecipe and RecordOutput during generation attempts. — yes
StudioBff sync-http Recipe and provenance views. — yes

Failure and recovery

Scenario Detection Recovery Data impact RTO (min)
Template version deprecated after approval AssetReleaseDeprecated via the catalog the recipe stays valid for its pinned version; a new version is offered; the run that executes it is not interrupted none 0

NFR targets

Target Class value (pilot-interactive) Override
latency_p95_ms 2000 —
availability_pct 99.5 —
throughput_rps 50 —
rpo_minutes 15 —
rto_minutes 240 —
cost_class low —

Deployment

Granularity module of host · host TemplateCatalogHost
Topologies saas-default, hybrid, on-prem
Runtime —; replicas —–—
Ports —

Current implementation

dotnet new with the ConnectSoft templates by hand; DerechHaLev is the proof that the templates compose into a product. No recipe, plan or provenance exists.

Later capabilities

Scaffold engine as a service (optional, ADR-0025); recipe diffs that drive re-scaffold rollouts with a generated-versus-hand-edited report; recipe templates per vertical (examples section).

Decisions and traceability

Family Ids
FR FR-03, FR-06, FR-07
FUX FUX-01, FUX-03
NFR NFR-11, NFR-13
XL XL-03, XL-07, XL-10