Epic #382 / relates #378 (W1/W2). Surfaced by #385 (composer): the frontend sends per-stage method selections (W1 StageMethodOptions), presetId (W2 ArtWorkflowPreset), and per-stage skip, but api/artstudio/submit currently binds only name/assetType/sourceType/prompt/image — the rest is silently dropped. Net effect: the W1 method choice, W2 preset application, and skip are non-functional end-to-end (the pipeline always runs its default stage plan/methods regardless of what the user picked).
Scope (event-handler-driven): wire the submit action to parse stageMethodSelections (JSON), presetId, and skippedStages, resolve the preset + per-stage method overrides against the existing W1/W2 domain, and thread the resolved plan into the pipeline kickoff — the stage command / workflow doc that ArtPipeProcessor consumes (RequestArtAssetStageCommand / the art.asset.lifecycle planning path) — so the chosen method/model actually runs per stage and skipped stages are omitted from the plan. Keep heavy work out of Api (MediatR → workers per worker-architecture rule); trace context preserved.
First: DISCOVER the intended flow — the W1/W2 domain exists; determine whether submit was meant to consume it (designed-but-unwired) or whether selections were meant to arrive via a separate endpoint. Don't fabricate a second path if submit is the right home.
Deps: the #385 composer already sends these fields forward-compatibly (staff-gated skip). Type: backend. Test: submit with method/preset/skip → the resulting stage plan/command reflects them (unit); untouched submit still yields the default plan (regression).
Epic #382 / relates #378 (W1/W2). Surfaced by #385 (composer): the frontend sends per-stage **method selections** (W1 `StageMethodOptions`), **`presetId`** (W2 `ArtWorkflowPreset`), and per-stage **skip**, but `api/artstudio/submit` currently binds only `name/assetType/sourceType/prompt/image` — the rest is **silently dropped**. Net effect: the W1 method choice, W2 preset application, and skip are non-functional end-to-end (the pipeline always runs its default stage plan/methods regardless of what the user picked).
**Scope (event-handler-driven):** wire the submit action to parse `stageMethodSelections` (JSON), `presetId`, and `skippedStages`, resolve the preset + per-stage method overrides against the existing W1/W2 domain, and thread the resolved plan into the pipeline kickoff — the stage command / workflow doc that `ArtPipeProcessor` consumes (`RequestArtAssetStageCommand` / the `art.asset.lifecycle` planning path) — so the chosen method/model actually runs per stage and skipped stages are omitted from the plan. Keep heavy work out of Api (MediatR → workers per worker-architecture rule); trace context preserved.
**First: DISCOVER the intended flow** — the W1/W2 domain exists; determine whether submit was meant to consume it (designed-but-unwired) or whether selections were meant to arrive via a separate endpoint. Don't fabricate a second path if submit is the right home.
**Deps:** the #385 composer already sends these fields forward-compatibly (staff-gated skip). **Type:** backend. **Test:** submit with method/preset/skip → the resulting stage plan/command reflects them (unit); untouched submit still yields the default plan (regression).
Correction after discovery — the gap was narrower than filed. Tracing ArtStudioController.Submit → SubmitArtAssetCommandHandler → RequestArtAssetStageCommand → ArtPipeProcessor showed that stageMethodSelections (W1) and presetId (W2) are already fully wired — the controller binds them, the handler resolves per-stage methods, loads/merges the preset, composes the prompt, attaches failover, and persists provenance. The #385 composer's "backend doesn't parse them" note was mistaken (it read a stale/partial view). Only skippedStages was genuinely dropped.
Fixed in local branch feature/artstudio-submit-selections-397 (unpushed): controller binds + JSON-parses skippedStages (400 on malformed), threads it through the command; handler normalizes + staff-gates it (reusing the W1 AllowStudentMethodChoice gate; non-staff skips rejected + audited via new StageSkipRejected), filters the persisted StagePlan (empty-plan guard), and prunes method overrides for skipped stages. Worker unchanged — it already walks StagePlan. No-skip path proven byte-identical (regression tests). Build clean; filtered ~ArtStudio|~Submit|~StageMethod|~Preset = 540 pass, +15 new tests. Semantic skip-validity (e.g. skipping modeling starves downstream) deliberately left to staff/pipeline — no mandatory-stage concept exists in the codebase to enforce. Will close on merge.
**Correction after discovery — the gap was narrower than filed.** Tracing `ArtStudioController.Submit → SubmitArtAssetCommandHandler → RequestArtAssetStageCommand → ArtPipeProcessor` showed that `stageMethodSelections` (W1) and `presetId` (W2) are **already fully wired** — the controller binds them, the handler resolves per-stage methods, loads/merges the preset, composes the prompt, attaches failover, and persists provenance. The #385 composer's "backend doesn't parse them" note was mistaken (it read a stale/partial view). **Only `skippedStages` was genuinely dropped.**
Fixed in local branch `feature/artstudio-submit-selections-397` (unpushed): controller binds + JSON-parses `skippedStages` (400 on malformed), threads it through the command; handler normalizes + **staff-gates** it (reusing the W1 `AllowStudentMethodChoice` gate; non-staff skips rejected + audited via new `StageSkipRejected`), filters the persisted `StagePlan` (empty-plan guard), and prunes method overrides for skipped stages. **Worker unchanged** — it already walks `StagePlan`. No-skip path proven byte-identical (regression tests). Build clean; filtered `~ArtStudio|~Submit|~StageMethod|~Preset` = **540 pass**, +15 new tests. Semantic skip-validity (e.g. skipping `modeling` starves downstream) deliberately left to staff/pipeline — no mandatory-stage concept exists in the codebase to enforce. Will close on merge.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Epic #382 / relates #378 (W1/W2). Surfaced by #385 (composer): the frontend sends per-stage method selections (W1
StageMethodOptions),presetId(W2ArtWorkflowPreset), and per-stage skip, butapi/artstudio/submitcurrently binds onlyname/assetType/sourceType/prompt/image— the rest is silently dropped. Net effect: the W1 method choice, W2 preset application, and skip are non-functional end-to-end (the pipeline always runs its default stage plan/methods regardless of what the user picked).Scope (event-handler-driven): wire the submit action to parse
stageMethodSelections(JSON),presetId, andskippedStages, resolve the preset + per-stage method overrides against the existing W1/W2 domain, and thread the resolved plan into the pipeline kickoff — the stage command / workflow doc thatArtPipeProcessorconsumes (RequestArtAssetStageCommand/ theart.asset.lifecycleplanning path) — so the chosen method/model actually runs per stage and skipped stages are omitted from the plan. Keep heavy work out of Api (MediatR → workers per worker-architecture rule); trace context preserved.First: DISCOVER the intended flow — the W1/W2 domain exists; determine whether submit was meant to consume it (designed-but-unwired) or whether selections were meant to arrive via a separate endpoint. Don't fabricate a second path if submit is the right home.
Deps: the #385 composer already sends these fields forward-compatibly (staff-gated skip). Type: backend. Test: submit with method/preset/skip → the resulting stage plan/command reflects them (unit); untouched submit still yields the default plan (regression).
Correction after discovery — the gap was narrower than filed. Tracing
ArtStudioController.Submit → SubmitArtAssetCommandHandler → RequestArtAssetStageCommand → ArtPipeProcessorshowed thatstageMethodSelections(W1) andpresetId(W2) are already fully wired — the controller binds them, the handler resolves per-stage methods, loads/merges the preset, composes the prompt, attaches failover, and persists provenance. The #385 composer's "backend doesn't parse them" note was mistaken (it read a stale/partial view). OnlyskippedStageswas genuinely dropped.Fixed in local branch
feature/artstudio-submit-selections-397(unpushed): controller binds + JSON-parsesskippedStages(400 on malformed), threads it through the command; handler normalizes + staff-gates it (reusing the W1AllowStudentMethodChoicegate; non-staff skips rejected + audited via newStageSkipRejected), filters the persistedStagePlan(empty-plan guard), and prunes method overrides for skipped stages. Worker unchanged — it already walksStagePlan. No-skip path proven byte-identical (regression tests). Build clean; filtered~ArtStudio|~Submit|~StageMethod|~Preset= 540 pass, +15 new tests. Semantic skip-validity (e.g. skippingmodelingstarves downstream) deliberately left to staff/pipeline — no mandatory-stage concept exists in the codebase to enforce. Will close on merge.✅ Merged to master via spikersoft-backend#101. Submit skip/method-selections wiring landed in
SubmitArtAssetCommandHandler(staff-gated stage skipping, persisted StagePlan filter). Build 0 errors; 534 ArtStudio tests green.