You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
They do not by themselves answer the separate lifecycle question:
Should this AI request/stream/task still be running, and what happens when it is stopped, superseded, duplicated, unmounted or abandoned?
Cancellation behavior is currently spread across hooks, thunks, provider adapters, workers, local inference paths and UI controls. #704 previously carried this as “Wave 0C”, but the umbrella is now too broad to serve as the durable implementation owner.
This issue owns the bounded AI request lifecycle contract across currently admitted WorldScript AI surfaces.
Core invariant
Cancellation and project authority are complementary and must remain independent:
PROJECT AUTHORITY
= may a late result/chunk mutate/apply/export to the current project?
REQUEST LIFECYCLE
= should the underlying work continue, be superseded, stop producing UI state, or release resources?
A cancelled operation may still deliver a late provider callback.
A non-cancelled operation may become stale because the user switched projects.
a superseded request is distinguishable from provider failure where product behavior differs;
“cancel requested” does not falsely imply the provider has definitely stopped if the transport/runtime cannot guarantee it;
stale late callbacks after terminal state cannot reopen the operation;
UI derives from authoritative request state rather than multiple drifting booleans where practical.
Do not over-engineer a distributed workflow engine.
3. AbortSignal propagation
For every provider/runtime path that supports cooperative cancellation, propagate one admitted cancellation signal from product orchestration to the lowest practical boundary.
Where a provider SDK cannot truly cancel remote generation, stop local consumption and rely on mutation/project guards for late data.
4. Stop Generation product contract
Inventory every visible Stop/Cancel control and define what it guarantees.
A correct Stop Generation action should normally mean:
user requests stop
→ request transitions to stopping/cancelled semantics
→ transport/runtime cancellation attempted
→ no subsequent late chunk/result is admitted to active UI/project state
→ loading/streaming indicator settles
→ controls return to a usable state
→ partial output policy is explicit
For each surface decide whether partial output is:
Use explicit request IDs/generation tokens where needed, but do not create a second project-incarnation authority.
6. Streaming admission
Streaming paths require stronger lifecycle discipline than one-shot requests.
For every stream:
chunk arrives
→ request identity still current?
→ lifecycle still admits chunks?
→ project/result authority still valid where mutation/apply-capable?
→ then update admitted state
At minimum audit:
Writer;
Global Copilot;
Character Interviews;
provider-native text streaming;
any local model token streaming.
After Stop/Supersede/Unmount:
late chunks are ignored deterministically;
no UI state reopens;
no stale transcript/history mutation occurs;
stream-reader/iterator resources are released where possible.
#708/#713 remain the source of project ownership truth.
7. Component unmount / navigation lifecycle
Audit what happens when users:
navigate away from a view;
close a modal/panel;
switch feature modes;
disable a feature flag;
close Global Copilot;
leave Character Interviews;
switch projects;
reset/import/restore;
log out of a provider-like integration if applicable;
close/reload the application.
Do not indiscriminately cancel every operation on every UI unmount if the product intentionally supports background completion.
Do not expose raw provider exception strings containing sensitive metadata.
Do not count intentional cancellation as ordinary feature failure in diagnostics/telemetry-like local evidence.
#551 owns broader structured diagnostic architecture; reuse its semantics where available rather than creating a disconnected logging taxonomy.
9. Timeout semantics
Cancellation and timeout are related but not identical.
Audit current timeouts across providers/local inference.
Required policy:
timeout values are workload/provider appropriate rather than one arbitrary global constant;
timeout aborts the request when supported;
timeout produces an actionable TIMEOUT state, not USER_CANCELLED;
fallback after timeout follows explicit routing policy;
no retry storm;
image/long-form/local-model workloads may legitimately need different thresholds;
mandatory tests use deterministic fake clocks/controlled transport where possible rather than sleeping for real timeout durations.
Do not tune production timeouts merely to make CI pass.
10. Provider/fallback-chain cancellation
#704 owns model/provider correctness; this issue owns lifecycle propagation through routing.
Verify:
cancel before provider attempt
cancel during primary
cancel between primary failure and fallback
cancel during fallback
cancel during retry/backoff
Cancellation must short-circuit further attempts unless the product explicitly defines otherwise.
A user pressing Stop must not result in another cloud provider being contacted because the aborted request was misclassified as a retryable network error.
Preserve privacy/local-only boundaries.
11. Local inference lifecycle
Audit currently admitted local runtimes:
Ollama / OpenAI-compatible local server
WebLLM
ONNX Runtime Web
Transformers.js
Where applicable verify:
request cancellation;
token-stream stop;
worker termination vs reusable worker state;
model remains loaded when appropriate after one request cancellation;
no model/device resource leak per cancel/retry cycle;
device-lost/OOM remains a separate failure state;
cancelling inference does not delete downloaded model artifacts;
editor/autosave responsiveness recovers promptly.
Coordinate broad browser-local model lifecycle with #483/#556; do not duplicate model catalogue or artifact-storage work here.
12. Images and non-streaming long operations
Image generation may not expose token streaming but still needs lifecycle correctness.
Audit Character/World/Scene image paths for:
duplicate generation clicks;
refinement superseding prior generation;
cancellation support of provider request where available;
Cancellation alone must never authorize a late persistent write.
13. ProForge / agentic workflows
ProForge can have multi-stage or HITL semantics.
Do not apply a naive single-request AbortController if the pipeline has meaningful stage boundaries.
Derive current production behavior and define:
cancel current stage;
cancel whole run;
pause/wait at HITL;
superseding a run;
background continuation policy;
partial artifacts/state after cancellation;
rollback/non-mutation guarantees;
provider calls already in flight.
Keep this bounded to lifecycle semantics; do not redesign the entire ProForge architecture.
14. Plugin ai.invoke
If currently production-admitted for plugins, ensure plugin-triggered AI requests cannot create unbounded uncancellable work.
Required where applicable:
bounded timeout;
cancellation/termination when plugin execution is terminated;
plugin does not receive provider credentials;
provider/privacy policy remains authoritative;
late result cannot apply project mutation without the plugin side-effect authority contract.
Coordinate marketplace/security evolution with #348; do not broaden this issue into plugin distribution.
15. Background AI tasks
Inventory any background AI/task paths currently reachable.
Each must explicitly classify lifecycle:
foreground-only
continue after view close
continue after project switch only if project-owned and authority-bound
cancel on app/page lifecycle
persistent resumable task
Do not invent persistent background execution for browser/PWA merely to make cancellation architecture uniform.
Once source lifecycle semantics are admitted, #710 should prove representative user journeys such as:
Writer stream → Stop → no late mutation
Character Interview → Stop → no late transcript mutation
Copilot → supersede/stop → only current result remains applicable
Do not duplicate every provider × cancellation permutation in Playwright.
Adapter/service/unit/integration tests carry the detailed lifecycle matrix.
#712 may select one production-bundle lifecycle canary only if it gives unique build/CSP/chunk signal.
20. Diagnostics / privacy-safe evidence
Record only lifecycle metadata needed for debugging, for example:
request kind
provider class/model id where non-sensitive
request id
start/end state
duration
cancel source
error category
application SHA/environment
Do not log:
manuscript content;
prompts/results;
API keys/tokens;
private filesystem paths;
provider account metadata.
Coordinate structured redaction/evidence format with #551/#704.
21. Implementation architecture constraints
Prefer reusable request-lifecycle semantics, but avoid an invasive rewrite merely for uniformity.
Good architecture should provide:
one caller-owned cancellation path
explicit request identity
explicit terminal state
late-event admission check
provider/runtime propagation
bounded cleanup
without forcing every provider to implement unsupported primitives.
Do not:
replace Redux/project authority with request IDs;
move all AI orchestration to Rust;
add a generic workflow framework unrelated to current needs;
make provider-specific limitations appear as universal guarantees;
silently change privacy fallback behavior.
Acceptance criteria
All production AI surfaces have an explicit cancellation/supersession lifecycle disposition.
A shared lifecycle vocabulary distinguishes success, failure, user cancellation, supersession, timeout and stale-project rejection where product behavior differs.
Caller cancellation propagates through routing/adapters to supported transport/runtime boundaries.
#708 direct/persistent/stream project authority
+
#713 deferred/apply-later project authority
↓
THIS ISSUE — Wave 0C request lifecycle
↓
#710 functional AI E2E
#711 opt-in admission where Stop/network policy matters
#712 selected production canaries
↓
#623 evidence-based required/advisory graduation
Bounded implementation PRs are preferred by surface/lifecycle primitive rather than one repository-wide mega-PR. Preserve current work and rebase sequencing on live repository state before execution.
Context
Dedicated Wave 0C child of #704.
WorldScript Studio now has an explicit project-incarnation correctness layer:
Those correctness layers answer:
They do not by themselves answer the separate lifecycle question:
Cancellation behavior is currently spread across hooks, thunks, provider adapters, workers, local inference paths and UI controls. #704 previously carried this as “Wave 0C”, but the umbrella is now too broad to serve as the durable implementation owner.
This issue owns the bounded AI request lifecycle contract across currently admitted WorldScript AI surfaces.
Core invariant
Cancellation and project authority are complementary and must remain independent:
A cancelled operation may still deliver a late provider callback.
A non-cancelled operation may become stale because the user switched projects.
Therefore:
1. Inventory every production AI lifecycle
Derive the authoritative inventory from current source, not historical assumptions.
Search every production path using or wrapping:
At minimum classify known surfaces such as:
streamGenerationThunk;ai.invokewhere admitted;Produce a lifecycle matrix:
Do not assume every operation needs a user-visible Stop button; classify intentionally.
2. Canonical request lifecycle vocabulary
Establish a small explicit state vocabulary sufficient for product/runtime correctness.
Conceptually:
Exact implementation may differ.
Requirements:
Do not over-engineer a distributed workflow engine.
3. AbortSignal propagation
For every provider/runtime path that supports cooperative cancellation, propagate one admitted cancellation signal from product orchestration to the lowest practical boundary.
Audit:
Required properties:
AbortControllersevers caller cancellation;AbortErrorand convert it into generic failure;Where a provider SDK cannot truly cancel remote generation, stop local consumption and rely on mutation/project guards for late data.
4. Stop Generation product contract
Inventory every visible Stop/Cancel control and define what it guarantees.
A correct Stop Generation action should normally mean:
For each surface decide whether partial output is:
Do not let individual hooks invent incompatible semantics accidentally.
Do not report cancellation as a provider/network error toast unless cancellation itself genuinely failed in an actionable way.
5. Supersession / latest-request semantics
Rapid repeated user actions can start overlapping work.
For each applicable surface decide explicitly:
Examples to inspect:
Requirements:
Use explicit request IDs/generation tokens where needed, but do not create a second project-incarnation authority.
6. Streaming admission
Streaming paths require stronger lifecycle discipline than one-shot requests.
For every stream:
At minimum audit:
After Stop/Supersede/Unmount:
#708/#713 remain the source of project ownership truth.
7. Component unmount / navigation lifecycle
Audit what happens when users:
Do not indiscriminately cancel every operation on every UI unmount if the product intentionally supports background completion.
Instead classify each operation:
Any operation that continues after view unmount must have an explicit result destination and ownership contract.
8. Error taxonomy: cancelled is not failed
Normalize cancellation-related error handling so user-visible behavior is truthful.
Distinguish at minimum:
Do not expose raw provider exception strings containing sensitive metadata.
Do not count intentional cancellation as ordinary feature failure in diagnostics/telemetry-like local evidence.
#551 owns broader structured diagnostic architecture; reuse its semantics where available rather than creating a disconnected logging taxonomy.
9. Timeout semantics
Cancellation and timeout are related but not identical.
Audit current timeouts across providers/local inference.
Required policy:
Do not tune production timeouts merely to make CI pass.
10. Provider/fallback-chain cancellation
#704 owns model/provider correctness; this issue owns lifecycle propagation through routing.
Verify:
Cancellation must short-circuit further attempts unless the product explicitly defines otherwise.
A user pressing Stop must not result in another cloud provider being contacted because the aborted request was misclassified as a retryable network error.
Preserve privacy/local-only boundaries.
11. Local inference lifecycle
Audit currently admitted local runtimes:
Where applicable verify:
Coordinate broad browser-local model lifecycle with #483/#556; do not duplicate model catalogue or artifact-storage work here.
12. Images and non-streaming long operations
Image generation may not expose token streaming but still needs lifecycle correctness.
Audit Character/World/Scene image paths for:
Cancellation alone must never authorize a late persistent write.
13. ProForge / agentic workflows
ProForge can have multi-stage or HITL semantics.
Do not apply a naive single-request AbortController if the pipeline has meaningful stage boundaries.
Derive current production behavior and define:
Keep this bounded to lifecycle semantics; do not redesign the entire ProForge architecture.
14. Plugin
ai.invokeIf currently production-admitted for plugins, ensure plugin-triggered AI requests cannot create unbounded uncancellable work.
Required where applicable:
Coordinate marketplace/security evolution with #348; do not broaden this issue into plugin distribution.
15. Background AI tasks
Inventory any background AI/task paths currently reachable.
Each must explicitly classify lifecycle:
Do not invent persistent background execution for browser/PWA merely to make cancellation architecture uniform.
PWA deferred work remains constrained by #488.
16. UI concurrency / control semantics
For every user-visible generation surface verify:
Coordinate broader accessibility requirements with #557.
17. Resource cleanup
Repeated generate/stop/regenerate cycles must not leak:
Add focused leak/lifecycle assertions where deterministic; do not introduce brittle heap-size CI gates without evidence.
18. Deterministic regression matrix
Required source/integration coverage should include representative permutations:
One-shot
Streaming
The last case must prove lifecycle + project-authority composition rather than assigning both responsibilities to one guard.
Fallback
Duplicate action
Use deterministic mocked provider/transport boundaries in mandatory CI.
19. Product-level E2E relationship
#710 owns the broad AI functional E2E inventory.
Once source lifecycle semantics are admitted, #710 should prove representative user journeys such as:
Do not duplicate every provider × cancellation permutation in Playwright.
Adapter/service/unit/integration tests carry the detailed lifecycle matrix.
#712 may select one production-bundle lifecycle canary only if it gives unique build/CSP/chunk signal.
20. Diagnostics / privacy-safe evidence
Record only lifecycle metadata needed for debugging, for example:
Do not log:
Coordinate structured redaction/evidence format with #551/#704.
21. Implementation architecture constraints
Prefer reusable request-lifecycle semantics, but avoid an invasive rewrite merely for uniformity.
Good architecture should provide:
without forcing every provider to implement unsupported primitives.
Do not:
Acceptance criteria
Non-goals
Priority / sequencing
P1 lifecycle correctness after/alongside terminal Wave 0B authority fixes.
Recommended dependency graph:
Bounded implementation PRs are preferred by surface/lifecycle primitive rather than one repository-wide mega-PR. Preserve current work and rebase sequencing on live repository state before execution.