Files
SuperBizAgent-java/openspec/changes/archive/2026-07-21-single-react-design-freeze/decisions.md
T

7.9 KiB

Decisions

Entry

  • Parent issue: ISS-014
  • Change: single-react-design-freeze
  • Scale: complex
  • Interface impact: future L4; this change freezes contracts without switching runtime behavior.
  • Capability sources: sm-flow built-in clarify/context/propose, grill-with-docs, openspec-propose, zoom-out, openspec-apply-change, openspec-archive-change.

Context Evidence

  • session-run-trace-isolation established Chat Session and Diagnosis Run as separate lifecycles and made runId the Trace ownership key.
  • verifier-evidence-reference-fidelity established that no-evidence is a scoped negative observation, not proof that a problem does not exist.
  • executor-composer-final-answer established deterministic safe fallback boundaries and prohibited unfiltered raw output from reaching users.
  • modular-rag-pipeline established that retrieval trace and context packing are audit details rather than direct facts.
  • Current Spring AI Alibaba ToolCallRequest already provides tool_call_id; Harness must validate and persist it rather than create a second identity.
  • Current Spring AI ChatModel.call(Prompt) has no cancellation token, so cancellation must be expressed as layered, observable semantics rather than an unsupported absolute guarantee.

Question Pool

ID Dimension Question Mode Status
Q1 Terminology Does tool_call_id use the framework ID or a Harness-generated ID? user-interview confirmed: framework ID
Q2 Terminology Are invocation lifecycle and evidence outcome separate fields? user-interview confirmed: status + evidence_status
Q3 Boundary Is ISS-014 one umbrella Issue with independent OpenSpec changes? user-interview confirmed: one Issue, 11 changes
Q4 Boundary May stage 4 publish before Guards exist? user-interview confirmed: no; public cutover only in 6B
Q5 Lifecycle What is the durable source of truth for previous_turn and last_intent? user-interview confirmed: diagnosis_run safe published result
Q6 Contract How is KNOWLEDGE_QUERY citation validation represented? evidence-driven resolved: structured answer items with exact RAG bindings
Q7 Cancellation What cancellation guarantees are technically enforceable? evidence-driven resolved: layered cancellation, no false hard-cancel claim
Q8 Acceptance Are Apply, Archive and phase Git commit pre-authorized? user-interview confirmed: yes, for all phases

Confirmed Decisions

  • tool_call_id is the framework Tool Call protocol ID. Harness validates non-empty, bounded, safe characters and Run-local uniqueness; duplicate/invalid/missing IDs fail closed.
  • Redis status=PROJECTING/READY/ERROR represents invocation/projector lifecycle.
  • evidence_status=EVIDENCE_FOUND/NO_EVIDENCE/ERROR represents result semantics.
  • NO_EVIDENCE may only support NEGATIVE_OBSERVATION within the exact query scope; it cannot prove absence, exclusion or health.
  • Stage 4 and 6A remain internal. Stage 6B performs the only public Chat cutover after stage 5 release gates pass.
  • ISS-014 remains the umbrella Issue. Eleven independent changes run serially; each must complete sm-flow, OpenSpec archive and Git commit before the next starts.
  • Full live E2E is deferred to stage 7; earlier stages run focused verification proportional to their change.
  • KNOWLEDGE_QUERY uses a dedicated structured draft: each answer item binds the single lookup tool_call_id and one or more returned document_id values; Harness validates exact membership before rendering answer + references + limitations. It does not reuse the Diagnosis Analysis schema and does not enter SemanticGuard in the first version.
  • Cancellation is layered: mark cancellation requested, prevent new model/Tool rounds and any final Draft release, invoke framework interruption, cancel owned Tool/JDBC work where supported, and rely on configured HTTP timeouts for an already-blocking synchronous model call. Run finalization is atomic and late results are discarded.
  • Public SSE done is not emitted after the client has disconnected; internal Run state still reaches CANCELLED.
  • diagnosis_run is the durable source for intent, release_outcome and published_result. Only the latest same-session DIAGNOSIS + SUCCESS record with a non-null safe published result may become previous_turn; FALLBACK/FAILED/CANCELLED remain auditable but are excluded.
  • published_result stores only user_query/published_conclusion/scope/limitations/source_documents; it excludes Tool Call IDs, raw evidence, full Draft and SemanticGuard audit reasons.

Evidence-Driven Findings To Report

  • The framework already exposes ToolInterceptor, structured output types, tool execution timeout, model/tool call limit hooks and ReactAgent.interrupt; later Harness stages should reuse these extension points.
  • Spring AI model dependencies include retry support, while current application configuration does not explicitly freeze all retry layers; stage 0 must define a retry inventory and stage 2 must enforce it.
  • Current DiagnosisRun stores a text answer and generic status but has no explicit intent, release_outcome or structured published result; Q5 must be resolved before the previous-turn contract is executable.
  • Current KNOWLEDGE_QUERY target behavior promises citation validation, but the issue only defines the Diagnosis Draft binding schema; the committed spec must add the dedicated answer-item contract described above.
  • Spring AI retry auto-configuration defaults maxAttempts to 10. The target Harness retry matrix requires underlying model/HTTP retries to be set to one attempt, with Router and SemanticGuard retries performed only by Harness.

OpenSpec Backfill

  • All confirmed decisions above must appear in design/specs/tasks before .committed is created.
  • All user-interview questions are confirmed; no pending decision blocks Commit.

Architecture Audit

Current input flows from ChatController into ChatService, which owns routing, ReactAgent construction, multi-Agent orchestration and final rendering; tools persist evidence through ToolInvocationRecorder, while Hooks and ThreadLocal bridge Run and verifier state. Stage zero introduces only dependency-free contract types under harness.contract; those types must not depend on Controller, Redis, JPA, Spring Agent state or current Hook classes. Later stages move ownership in order: RunContext, invocation store, Tool-specific projection, Diagnosis Agent, Guards, application use case and finally the public SSE adapter. diagnosis_run remains durable Run ownership, Redis canonical invocation remains short-lived Harness ownership, and agent_step/tool_invocation remain durable audit detail. The principal risk is spec/runtime drift, mitigated by archiving only the stage-zero contract capability now and delaying modifications to existing runtime capabilities until their implementation changes.

Cross-Artifact Alignment

Chain Status Evidence
ISS-014/brief goals, scope and non-goals → proposal aligned Proposal limits stage zero to contracts, security and baseline with no public cutover.
proposal commitments → design aligned Design records every ID, status, Draft, fallback, previous-turn, retry, cancellation and phase-gate commitment.
design decisions → specs aligned The single stage-zero capability has testable requirements for every stable contract boundary.
specs observable behavior → tasks aligned Tasks create reusable types/tests, remove the secret, align artifacts and verify without switching runtime behavior.

Commit Gate Result

  • Question pool covers terminology, boundary, lifecycle, contract, cancellation and acceptance.
  • All user-interview items are explicitly confirmed.
  • Evidence-driven conclusions were reported and written into design/spec/tasks.
  • Interface impact is recorded as future L4; this change itself does not switch the public API.
  • No devflow/OpenSpec conflict remains.