Add repairable INVALID_PROGRESS_PROTOCOL observations, independent PROGRESS_PROTOCOL_VIOLATED saturation, and controlled release paths. Archive the OpenSpec change after syncing main specs and devflow.
8.5 KiB
single-react-chat-application-usecase Specification
Purpose
TBD - created by archiving change single-react-chat-application-usecase. Update Purpose after archive.
Requirements
Requirement: Application-owned session and Run lifecycle
The Chat Application Use Case SHALL resolve or generate the session ID, create exactly one RunContext, persist one matching Diagnosis Run, and propagate the same session ID, run ID, original Query, cancellation, budget, and terminal outcome through routing and the selected executor.
Scenario: Existing session request
- WHEN an internal request supplies a valid session ID
- THEN the use case preserves it, generates one run ID, and returns/persists the same identifiers
Scenario: New session request
- WHEN an internal request omits the session ID
- THEN the use case generates one valid session ID and uses it for all Run operations
Requirement: Minimal isolated Intent Router
The Router SHALL execute a direct no-Tool, no-memory, no-ReAct ChatModel call whose input contains only the unchanged Query, optional last intent, and optional last user Query. It SHALL accept only SYSTEM_CHAT, KNOWLEDGE_QUERY, or DIAGNOSIS.
Scenario: Three valid routes
- WHEN the model returns each supported enum in the strict output schema
- THEN the use case dispatches to exactly the corresponding fixed executor
Scenario: New topic overrides history
- WHEN the current Query identifies a new topic while prior routing context exists
- THEN the model input still preserves the original current Query and prior fields are only optional context
Requirement: Router technical retry fails closed
The Router SHALL use HarnessRetryPolicies.intentRouter() and SHALL retry timeout, transport, or invalid output at most once with identical input. A second failure MUST produce ROUTING_UNAVAILABLE and MUST NOT dispatch Diagnosis.
Scenario: Invalid output then valid route
- WHEN the first output is not a supported enum and the second output is valid
- THEN exactly two attempts use the same input and the valid route is executed
Scenario: Two invalid outputs
- WHEN both permitted attempts return invalid output
- THEN the Run ends FAILED and no intent executor is called
Requirement: Fixed isolated executors
The Application Use Case SHALL map SYSTEM_CHAT to one no-Tool model response, KNOWLEDGE_QUERY to exactly one lookup-knowledge invocation plus one bounded answer model call, and DIAGNOSIS to the single Diagnosis Agent followed by the Diagnosis Release boundary. Executors MUST NOT call one another or rewrite the Query. Information saturation and budget termination in Diagnosis SHALL be converted to safe content by Diagnosis Release, not by ChatApplicationUseCase.
Scenario: System Chat
- WHEN intent is SYSTEM_CHAT
- THEN no evidence Tool, Diagnosis Agent, EvidenceGuard, or SemanticGuard is invoked
Scenario: Knowledge Query
- WHEN intent is KNOWLEDGE_QUERY
- THEN only lookup_knowledge is invoked once and query_logs/query_mysql/Diagnosis ReAct are unavailable
Scenario: Diagnosis succeeds with a conclusion
- WHEN intent is DIAGNOSIS and the Draft passes the release guards
- THEN the original Query and bounded PreviousTurn enter DiagnosisAgentUseCase and the Draft publishes only after DiagnosisReleaseUseCase
Scenario: Diagnosis stops without a conclusion
- WHEN Diagnosis collection is saturated, required context is missing, or a handled budget limit is reached
- THEN DiagnosisReleaseUseCase returns bounded Fallback content and ChatApplicationUseCase only persists and transports that decision
Requirement: Knowledge references are physically validated
The Knowledge executor SHALL accept only a bounded READY RAG projection, SHALL validate every model answer item against the exact direct invocation ID and returned document ID set, and SHALL remove Tool Call IDs from public content.
Scenario: Supported knowledge answer
- WHEN answer items reference the exact lookup call and only returned documents
- THEN public content contains answer text, stable document references, and limitations without Tool Call IDs
Scenario: Fabricated knowledge reference
- WHEN the model returns another call ID or an unknown document ID
- THEN the executor fails closed and no knowledge answer is published
Scenario: No knowledge evidence
- WHEN lookup returns READY
NO_EVIDENCE - THEN the executor returns a fixed bounded no-evidence answer without calling the answer model
Requirement: Safe bounded PreviousTurn
The system SHALL load PreviousTurn only from the same Session's most recent Run with intent=DIAGNOSIS, release_outcome=SUCCESS, and non-null valid published_result. It SHALL deterministically bound fields and source documents without model summarization.
Scenario: Last safe Diagnosis exists
- WHEN a qualifying Run contains valid PublishedResult JSON
- THEN the next Diagnosis receives its bounded query, conclusion, scope, limitations, and RAG document metadata
Scenario: Last Run is fallback failed or cancelled
- WHEN newer Runs are not qualifying safe Diagnosis successes
- THEN they cannot become PreviousTurn and the query returns the most recent qualifying record or null
Scenario: Published result is corrupt
- WHEN stored JSON is invalid or required safe fields are blank
- THEN PreviousTurn is null and no raw stored value reaches a model
Requirement: Diagnosis Run persistence contract
The diagnosis_run schema SHALL add nullable intent, release_outcome, and JSON published_result, and the JPA entity/repository/store SHALL write and query them consistently. PublishedResult MUST NOT contain Tool IDs, raw evidence, full Draft, or SemanticGuard reasons.
Scenario: Successful Diagnosis completion
- WHEN a Diagnosis report with non-null conclusion is safely released
- THEN the Run stores intent DIAGNOSIS, release outcome SUCCESS, safe public answer, bounded PublishedResult, duration and budget usage
Scenario: Fallback completion
- WHEN release returns SafeFallback
- THEN the Run status is SUCCESS, release outcome is FALLBACK, and published_result is null
Scenario: Failure or cancellation
- WHEN routing/execution fails or the client cancels the Run
- THEN the Run stores exactly one FAILED or CANCELLED release outcome and no PublishedResult
Requirement: Protocol-neutral progress and cancellation
The use case SHALL notify a protocol-neutral observer after the Run is persisted, expose only session/run identifiers and client-disconnect cancellation, and emit only fixed safe application status codes.
Scenario: Observer start and status
- WHEN internal execution begins
- THEN observer start occurs once before routing status and contains the persisted session/run identifiers
Scenario: Client disconnect control
- WHEN the observer invokes client-disconnect cancellation
- THEN the same RunContext is cancelled and late executor results cannot complete successfully
Requirement: Stage-six-A public isolation
Stage 6A SHALL NOT modify or switch public Chat Controller endpoints, SSE contracts, frontend consumers, or legacy ChatService behavior.
Scenario: Internal-only delivery
- WHEN stage 6A changes are inspected
- THEN Controller/frontend/public endpoint behavior has zero diff and stage 6B can consume the completed use case without rewriting it
Requirement: Handled Diagnosis budget termination SHALL remain a Fallback release
When Diagnosis Release has converted a recognized budget termination and existing safe progress into a Fallback, ChatApplicationUseCase SHALL persist that result exactly once without reclassifying it as INTERNAL_FAILURE, invoking another model, or rebuilding business fallback content. The internal Run lifecycle MAY retain BUDGET_EXHAUSTED, while the persisted public release outcome SHALL be FALLBACK and no PublishedResult SHALL be stored.
Scenario: Tool budget ends after finite checks
- WHEN Diagnosis reaches a hard Tool budget after at least one canonical safe observation and Release creates an insufficient-evidence fallback
- THEN the Run persists status SUCCESS, release outcome FALLBACK, safe content and actual budget usage, and the SSE sends content followed by done
Scenario: Budget ends without safe publishable progress
- WHEN budget termination occurs before Diagnosis Release can form a safe bounded result
- THEN the existing failure path remains fail closed and does not fabricate observed facts