Art Studio: reproduce and vary a recorded run (#842) #847

Open
opened 2026-07-25 20:22:24 +00:00 by spikerj · 1 comment
Owner

Reproduce EXTENDS the restart endpoint with an optional body rather than adding a new one — restart already owns the semantics reproduce needs (cancel active runs, prune at-and-after, increment retry, re-moderate, re-dispatch) plus the rate limit and owner check. A null body stays byte-identical to the previous behaviour, which also keeps the deployed client (it posts null) working; that has an anchor test.

Modes: baseline run id → Exact; + NewSeed → Varied; explicit overrides → Tweaked. The baseline is validated against both the asset AND the stage — against the asset because otherwise a caller could read another user's recorded settings via a foreign run id, against the stage because a concept seed replayed into a mesh generator is meaningless.

PromptDrifted is the honesty flag: the worker always receives the asset's CURRENT prompt (prompt text cannot ride the restart path), so an 'exact' reproduce is exact only modulo prompt drift and the UI must say so. InvalidatedStages ships so the user is warned before a reproduce discards a rig they waited on.

Submit-time params land here too, including the negative prompt — free text on an image model is a known jailbreak vector, so it goes through the same moderation gate as the prompt and is then injected server-side from the stored value.

ArtStudio:GenerationParams:Enabled defaults FALSE so the API cannot outrun the workers.

Reproduce EXTENDS the restart endpoint with an optional body rather than adding a new one — restart already owns the semantics reproduce needs (cancel active runs, prune at-and-after, increment retry, re-moderate, re-dispatch) plus the rate limit and owner check. A null body stays byte-identical to the previous behaviour, which also keeps the deployed client (it posts `null`) working; that has an anchor test. Modes: baseline run id → Exact; + NewSeed → Varied; explicit overrides → Tweaked. The baseline is validated against both the asset AND the stage — against the asset because otherwise a caller could read another user's recorded settings via a foreign run id, against the stage because a concept seed replayed into a mesh generator is meaningless. `PromptDrifted` is the honesty flag: the worker always receives the asset's CURRENT prompt (prompt text cannot ride the restart path), so an 'exact' reproduce is exact only modulo prompt drift and the UI must say so. `InvalidatedStages` ships so the user is warned before a reproduce discards a rig they waited on. Submit-time params land here too, including the negative prompt — free text on an image model is a known jailbreak vector, so it goes through the same moderation gate as the prompt and is then injected server-side from the stored value. `ArtStudio:GenerationParams:Enabled` defaults FALSE so the API cannot outrun the workers.
Author
Owner

Audited against origin/masterthe feature works, but two documented behaviours don't exist. Staying open.

Landed: optional body on the existing endpoint (ArtStudioController.cs:762-789, DTO :1624-1628); handler-level anchor test for the plain restart (RestartFromStageCommandHandlerTests.cs:411-429) plus controller tests passing body: null (ArtStudioControllerTests.cs:758-774); Exact/Varied/Tweaked (ArtAssetGenerationParams.cs:283-293, resolved at RestartFromStageCommandHandler.cs:355-368); baseline validated against asset and stage before any mutation (:235-286, called at :76); PromptDrifted (:276-284); InvalidatedStages (:213); negative prompt through the identical moderation gate (SubmitArtAssetCommandHandler.cs:689-713, mirroring :670-687) then injected server-side from the stored value (ArtPipeStageOrchestrator.cs:982-990).

Remaining 1 — the ArtStudio:GenerationParams:Enabled master switch is dead code. It is declared at ArtStudioGenerationParamPolicy.cs:37 and documented as "False (the default) rejects every override", but no code path ever reads it:

  • Normalize() (:77-117) doesn't consult it.
  • git grep -n "generationParamPolicy\.Enabled\|GenerationParamPolicy\.Enabled" origin/master → no output. The only references are the declaration and a test asserting the default (ArtStudioGenerationParamPolicyTests.cs:186-190).
  • No appsettings sets the section: git grep -n "GenerationParams" origin/master -- '*.json' → no output, and nothing in spikersoft-infrastructure either.

Net effect: overrides are accepted in production right now, regardless of the flag. The feature being live may well be fine — but the stated safety property ("the API cannot outrun the workers") does not exist, and the documentation says it does. Either wire the flag into Normalize() or delete it and the doc comment.

Remaining 2 — MethodKey is accepted and ignored. It travels from the request body to the command (ArtStudioController.cs:789, RestartFromStageCommand.cs:43-44) but is never read: git grep -n "request.MethodKey" origin/master -- SpikerSoft.Business/Domain/ArtStudio → no output. ResolveStageMethods (:370-394) resolves purely from asset.StageMethodSelections. So "reproduce this on a different model" silently reproduces it on the same model — the caller gets a 200 and the wrong thing happens.

Both are small fixes; the first is the one with a correctness story attached.

Audited against `origin/master` — **the feature works, but two documented behaviours don't exist.** Staying open. **Landed:** optional body on the existing endpoint (`ArtStudioController.cs:762-789`, DTO `:1624-1628`); handler-level anchor test for the plain restart (`RestartFromStageCommandHandlerTests.cs:411-429`) plus controller tests passing `body: null` (`ArtStudioControllerTests.cs:758-774`); Exact/Varied/Tweaked (`ArtAssetGenerationParams.cs:283-293`, resolved at `RestartFromStageCommandHandler.cs:355-368`); baseline validated against asset **and** stage before any mutation (`:235-286`, called at `:76`); `PromptDrifted` (`:276-284`); `InvalidatedStages` (`:213`); negative prompt through the identical moderation gate (`SubmitArtAssetCommandHandler.cs:689-713`, mirroring `:670-687`) then injected server-side from the stored value (`ArtPipeStageOrchestrator.cs:982-990`). **Remaining 1 — the `ArtStudio:GenerationParams:Enabled` master switch is dead code.** It is declared at `ArtStudioGenerationParamPolicy.cs:37` and documented as *"False (the default) rejects every override"*, but **no code path ever reads it**: - `Normalize()` (`:77-117`) doesn't consult it. - `git grep -n "generationParamPolicy\.Enabled\|GenerationParamPolicy\.Enabled" origin/master` → no output. The only references are the declaration and a test asserting the default (`ArtStudioGenerationParamPolicyTests.cs:186-190`). - No appsettings sets the section: `git grep -n "GenerationParams" origin/master -- '*.json'` → no output, and nothing in spikersoft-infrastructure either. Net effect: **overrides are accepted in production right now, regardless of the flag.** The feature being live may well be fine — but the stated safety property ("the API cannot outrun the workers") does not exist, and the documentation says it does. Either wire the flag into `Normalize()` or delete it and the doc comment. **Remaining 2 — `MethodKey` is accepted and ignored.** It travels from the request body to the command (`ArtStudioController.cs:789`, `RestartFromStageCommand.cs:43-44`) but is never read: `git grep -n "request.MethodKey" origin/master -- SpikerSoft.Business/Domain/ArtStudio` → no output. `ResolveStageMethods` (`:370-394`) resolves purely from `asset.StageMethodSelections`. So "reproduce this on a different model" silently reproduces it on the *same* model — the caller gets a 200 and the wrong thing happens. Both are small fixes; the first is the one with a correctness story attached.
Sign in to join this conversation.