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"))
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
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
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
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 |