Skip to content

feat(platform): complete guided learning and harden streaming, ingestion, and deploys - #109

Merged
WilliamAGH merged 54 commits into
mainfrom
dev
Jul 18, 2026
Merged

feat(platform): complete guided learning and harden streaming, ingestion, and deploys#109
WilliamAGH merged 54 commits into
mainfrom
dev

Conversation

@WilliamAGH

@WilliamAGHWilliamAGH commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Summary

Java learners can now open every guided lesson, receive stable streamed answers from the explicitly selected LLM provider, and navigate without obsolete lesson or chat callbacks changing the active view. Ingestion and model-output contracts now fail clearly on ambiguous input, while local, CI, and container verification share one reproducible toolchain and deployments prove the exact source revision they run.

Changes

Learner experience

  • Complete guided curriculum: Every table-of-contents slug resolves to packaged lesson Markdown, so guided navigation no longer reaches missing resources (GuidedLearningService, src/main/resources/guided/lessons/).
  • Lifecycle-safe streaming: Unmounted chat requests and replaced lesson or guided-chat requests are aborted; ownership guards prevent stale text, citations, status, provider details, errors, and scroll indicators from mutating the active view (ChatView, LearnView).
  • Stable terminal errors: Backpressure overflow and provider cooldown end the stream with the shared retryable error contract, and partial assistant responses are not committed to chat history (SseSupport, ChatController, GuidedLearningController).
  • Faithful Markdown and citations: Fenced and indented code retain their list context, Unicode-blank enrichments disappear, Javadoc member anchors remain distinct, and PDF query/fragment links retain their destinations (MarkdownNormalizer, InlineListParser, RetrievalService, frontend/src/lib/utils/url.ts).

Provider, model, and ingestion contracts

  • Configured-provider-only dispatch: Streaming and completion reserve capacity immediately before dispatch, share cooldown admission, and never silently route a failed request through a different provider (OpenAiProviderRoutingService, OpenAIStreamingService).
  • Strict request and model output: Chat requires meaningful Unicode-visible latest input; enrichment accepts one complete typed JSON object; reranking requires an exact document permutation (ChatStreamRequest, EnrichmentService, RerankerService).
  • Deterministic documentation ingestion: Malformed UTF-8 fails before chunking or Qdrant writes, manifest-backed Java API sources share one classifier, and provenance changes invalidate stale ingestion markers (FileOperationsService, JavaPackageExtractor, IngestionProvenanceDeriver).
  • Canonical catalogs: Documentation sources, Java API mirrors, and enrichment presentation project their manifests instead of maintaining duplicate inventories (documentation-sources.manifest, java-api-documentation-sources.manifest, enrichment-kinds.manifest).

Configuration, verification, and deployment

  • Fail-fast configuration without tracked secrets: Provider selection, matching credentials, reasoning effort, embedding settings, and reranker settings are validated through their canonical owners; Qdrant and embedding credentials come directly from process environment (AppProperties, RequiredCredentialValidation, QdrantClientConfig, RemoteEmbedding).
  • Canonical remote embedding deployment: The non-secret Novita endpoint and provider-qualified model are owned by application.properties; credentials activate the provider without restoring removed environment aliases, runtime and ingestion preflight apply the same selection semantics, and deployment-shaped startup tests cover both remote and explicit OpenAI selection (EmbeddingConfig, RemoteEmbedding, embedding_preflight.sh, EmbeddingConfigStartupTest).
  • One reproducible Java distribution: Local version managers, Gradle, GitHub Actions, and backend container stages use BellSoft Liberica 25.0.3+11 (.tool-versions, build.gradle.kts, .github/workflows/build.yml, Dockerfile).
  • Warning-free serialized verification: Backend and frontend build output is serialized through a cross-platform kernel file lock; lint covers production and test code, expected negative-path logs are explicit, and Ubuntu CI exercises the lock wrapper (BuildStateLock, Makefile, ExpectedLogEvents).
  • Exact deployment identity: Runtime info exposes sanitized deployment/build metadata, and Docker smoke requires both commit fields to equal the GitHub Actions SHA before the deploy is accepted (SecurityConfig, JavaChatApplicationTests, .github/workflows/build.yml).
  • Current operational documentation: Setup, provider selection, reranking, deferred Qdrant initialization, frontend CI, ingestion, and Markdown ownership guidance now describe the shipped architecture rather than removed fallback paths.

Breaking changes

  • Runtime LLM fallback is removed. Set LLM_PRIMARY_PROVIDER to github_models or openai, provide that provider's matching credential, and restart to switch providers.
  • POST /api/chat/stream accepts latest only; clients using the legacy message field must migrate.
  • SSE consumers read provider identity from the dedicated provider event; removed fallback attempt fields are no longer emitted.
  • Malformed UTF-8 local documents fail ingestion instead of being replacement-decoded.
  • Development and container Java environments require BellSoft Liberica 25.0.3+11.

Validation

  • Local pre-push gate: backend build and all 530 tests passed; SpotBugs, PMD, ast-grep, frontend lint, type-aware lint, Svelte diagnostics, and production frontend build passed with zero warnings.
  • Frontend unit suite: 15 files and 133 tests passed.
  • Concurrent build-lock smoke: two commands completed serially and propagated child exit status.
  • GitHub Actions at a214437: both the push run and pull-request run passed frontend, Java build, Ubuntu build-lock smoke, and exact-SHA Docker runtime identity checks.
  • Coolify dev deployment hpkpo3o35k7uj9wamqqizn2f: deployment.commit and build.commit both equal a21443783082f4beddd1f3539c5fe2ffa51fa2a9; health, readiness, liveness, and dependency health remained HTTP 200/UP across two checks 30 seconds apart.
  • Live dogfood at dev.javachat.ai: cited chat streaming, guided lesson content, lesson-scoped chat, desktop/mobile navigation, and all observed API requests passed with no browser console or page errors.

detail-appBotand others added 30 commits July 13, 2026 16:40
Pin the current Liberica release across mise, CI, Docker, and Gradle.
Document the shared vendor and patch-version workflow for local development.
Bind the system prompt to AppProperties instead of a duplicate value injection.
Keep marker clauses in the canonical prompt without format-string warnings.
Resolve supported reasoning values from the OpenAI SDK during bean creation.
Fail lazy application startup immediately for invalid configuration.
Abort the active request when the chat view unmounts or is replaced.
Ignore callbacks and failures from streams that no longer own the view state.
Ignore query strings and fragments when identifying PDF citations.
Support case-insensitive HTTP schemes and local citation paths consistently.
Discard Unicode-blank enrichment markers without exposing raw source text.
Keep CommonMark fences and their code indentation inside numbered list items.
Skip non-terminal title and prose abbreviations while finding trailing text.
Treat corporate suffix punctuation as a valid sentence boundary.
Request strict JSON objects and reject preambles, malformed data, and unknown fields.
Include context snippets in the default Spring cache identity.
Replace independently mutable health fields with one atomic snapshot.
Report active checks accurately and keep failure timestamps monotonic.
Reserve provider capacity atomically immediately before SDK dispatch.
Surface configured-provider failures without cross-provider fallback and remove dead retry protocol state.
Accumulate only SSE chunks that survive bounded backpressure.
Synchronize rate-limit deadline reads, replacement, and expiry clearing.
Prove concurrent checks cannot erase a newly recorded provider deadline.
Require the model response to contain every source index exactly once.
Reject prose, fences, unknown fields, duplicates, omissions, and invalid indices.
Use final citation URLs as identity for resolvable sources.
Keep member and page fragments distinct while retaining opaque local identities.
Resolve wrapped gRPC statuses through the canonical API and typed timeouts.
Retry deadline and unavailable failures while rejecting quota and invalid-input statuses.
Remove replacement-character decoding from local file reads.
Surface malformed source files as observable ingestion failures before storage.
Use one Java API path discriminator for remote and local ingestion.
Verify manifest-mapped Javadocs reach the structured extractor.
Remove the legacy message alias and require a meaningful latest field.
Reject missing, null, blank, Unicode-blank, and legacy request bodies at the HTTP boundary.
Bound and neutralize untrusted slug text before placing it in exception details.
Cover control-character injection at the web boundary.
Bind startup validation and availability to the configured provider so mismatched credentials fail fast.
Remove runtime fallback notices while preserving selected-provider SSE transparency and aligned documentation.
Clear pending off-screen update indicators when chat or lesson context changes without disturbing same-lesson retries.
Split catalog and lesson-content lifecycles out of LearnView so each state owner remains bounded and independently testable.
Constructing an unselected provider client allowed stale secondary settings to abort application startup.
Initialize only the provider selected by configuration and cover both provider directions.
- Ignore invalid GitHub Models settings when OpenAI is selected
- Ignore invalid OpenAI settings when GitHub Models is selected
The lesson update reset was coupled to an unapproved component split and incomplete asynchronous lifecycle handling.
Keep the legacy LearnView boundary while making stream identity, cancellation, and provider status explicit.
- Reset off-screen indicators across clear and lesson changes
- Reject stale same-lesson citation callbacks and cancel streams on unmount
- Surface the selected provider in chat and guided-chat status
Keep cooldown classification and rate-limit reservation under one routing-owned boundary so streaming cannot dispatch through a newly active cooldown.
Permanent authentication, authorization, and not-found failures remain non-retryable instead of becoming transient on the next request.
- validate configured provider backoff at startup
- reserve immediately before completion or text-stream dispatch
- cover permanent failures and subscription-time cooldown races
@coderabbitai

coderabbitaiBot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR standardizes the Liberica Java toolchain, enforces explicit single-provider routing, removes streaming fallback notices, adds provider-aware SSE handling and cancellation guards, and tightens JSON, markdown, citation, ingestion, and concurrency behavior.

Changes

Configured provider and toolchain

Layer / File(s)Summary
Toolchain and provider configuration
.tool-versions, build.gradle.kts, .github/workflows/*, Dockerfile, docs/*, README.md, .env.example, src/main/resources/*
Java builds and images use BellSoft Liberica 25.0.3+11; provider setup documents explicit provider selection and matching credentials.
Provider admission and streaming
src/main/java/.../OpenAIStreamingService.java, OpenAiProviderRoutingService.java, RateLimit*.java, ChatController.java, GuidedLearningController.java, SseSupport.java
Requests use one configured provider with admission, cooldown, and rate-limit reservation; fallback notice streams and related payload fields are removed.
Frontend streaming lifecycle
frontend/src/lib/components/{ChatView,LearnView}.svelte, frontend/src/lib/services/*, frontend/src/lib/composables/*
Provider events are forwarded to UI state, while active streams are aborted and stale callbacks or citations are ignored.
Markdown, citations, and ingestion
src/main/java/.../markdown/*, frontend/src/lib/services/markdown.ts, frontend/src/lib/utils/url.ts, src/main/java/.../ingestion/*
Unicode-blank enrichment, inline-code fences, PDF labels, citation identity, Java API extraction, and retrieval error classification are updated.
Strict contracts and validation
EnrichmentService.java, RerankerService.java, ChatStreamRequest.java, OpenAiRequestFactory.java, src/test/*, frontend/src/**
LLM JSON, reranking permutations, request payloads, reasoning settings, health state, and rate-limit concurrency behavior receive stricter validation and coverage.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
participant Client
participant ChatView
participant ChatController
participant OpenAIStreamingService
participant ConfiguredProvider
Client->>ChatView: Send message
ChatView->>ChatController: Start stream with AbortSignal
ChatController->>OpenAIStreamingService: Request configured-provider stream
OpenAIStreamingService->>ConfiguredProvider: Admit and stream request
ConfiguredProvider-->>ChatController: Provider, status, text, and citations
ChatController-->>ChatView: SSE events
ChatView-->>Client: Render active stream
Loading

Possibly related issues

Possibly related PRs

Suggested labels:refactor

Poem

Liberica lights the build tonight,
One chosen provider streams just right.
Stale words drift away,
Fences hold their sway,
Citations land in clear daylight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 53.91% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title is concise and matches the PR’s broad focus on guided learning, streaming hardening, ingestion, and deployment updates.
Description check✅ PassedThe description is clearly aligned with the changeset and summarizes the main behavior, contract, and deployment updates.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitaicoderabbitaiBot added the refactor Code refactoring label Jul 17, 2026

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens “single configured provider” behavior across backend + frontend streaming chat, hardens structured-output parsing (enrichment/rerank), improves citation identity fidelity, and aligns local/CI/container Java builds on a pinned BellSoft Liberica release.

Changes:

  • Removes silent multi-provider fallback paths and surfaces provider identity via a dedicated SSE provider event.
  • Adds strict request/response contracts (canonical latest query for chat; strict JSON-only enrichment/rerank parsing).
  • Improves streaming lifecycle isolation in the UI (abort/ignore stale callbacks) and strengthens Markdown/enrichment/citation handling.

Reviewed changes

Copilot reviewed 101 out of 102 changed files in this pull request and generated 5 comments.

Show a summary per file
FileDescription
src/test/java/com/williamcallahan/javachat/web/SseSupportTest.javaAdds backpressure overflow assertions for coalesced chunk buffering/accumulation.
src/test/java/com/williamcallahan/javachat/web/GuidedSseCitationEventTest.javaUpdates mocks for StreamingResult API change (no notices flux).
src/test/java/com/williamcallahan/javachat/web/GuidedLearningControllerTest.javaVerifies slug sanitization in exception message (control char removal).
src/test/java/com/williamcallahan/javachat/web/GuidedLearningControllerStreamingFailureTest.javaUpdates mocks for StreamingResult API change.
src/test/java/com/williamcallahan/javachat/web/ChatStreamRequestTest.javaAdds request-contract tests requiring latest and rejecting legacy/malformed bodies.
src/test/java/com/williamcallahan/javachat/web/ChatControllerStreamingFailureTest.javaUpdates controller callsites for new ChatStreamRequest shape and StreamingResult change.
src/test/java/com/williamcallahan/javachat/support/RetrievalErrorClassifierTest.javaAdds retry classification tests for timeout + gRPC statuses.
src/test/java/com/williamcallahan/javachat/service/StreamingAttemptContextTest.javaRemoves tests for deleted multi-provider streaming-attempt context.
src/test/java/com/williamcallahan/javachat/service/RetrievalServiceTest.javaExpands citation identity tests for anchored Javadoc and PDF page fragments.
src/test/java/com/williamcallahan/javachat/service/RerankerServiceTest.javaAdds strict invalid JSON/order rejection tests; asserts deterministic ordering.
src/test/java/com/williamcallahan/javachat/service/RateLimitStateTest.javaAdds concurrent window-expiry and deadline-preservation tests.
src/test/java/com/williamcallahan/javachat/service/ProviderCircuitStateTest.javaAdds daily-limit reservation concurrency tests and injects deterministic time.
src/test/java/com/williamcallahan/javachat/service/OpenAiRequestFactoryTest.javaAdds startup validation tests for reasoning-effort config and normalization.
src/test/java/com/williamcallahan/javachat/service/markdown/MarkdownNormalizerTest.javaAdds normalization tests preserving fence indentation under numeric headers.
src/test/java/com/williamcallahan/javachat/service/markdown/MarkdownFenceRenderingTest.javaAdds HTML rendering assertions for fence fidelity after normalization.
src/test/java/com/williamcallahan/javachat/service/markdown/InlineListParserTest.javaAdds abbreviation-aware trailing-text parsing tests.
src/test/java/com/williamcallahan/javachat/service/markdown/EnrichmentPlaceholderizerTest.javaAdds Unicode-blank enrichment discard coverage and multiline-inline-code cases.
src/test/java/com/williamcallahan/javachat/service/ingestion/MalformedUtf8LocalDocsIngestionTest.javaProves malformed UTF-8 is rejected pre-chunking/indexing with observable failure.
src/test/java/com/williamcallahan/javachat/service/ingestion/LocalDocsFileIngestionProcessorTest.javaVerifies manifest-mapped local Javadocs use structured extraction + correct URL mapping.
src/test/java/com/williamcallahan/javachat/service/ExternalServiceHealthTest.javaAdds backoff overflow capping and healthSnapshot message/state agreement checks.
src/test/java/com/williamcallahan/javachat/service/EnrichmentServiceTest.javaVerifies JSON-object-only enrichment completion boundary and strict parsing failures.
src/test/java/com/williamcallahan/javachat/service/EnrichmentServiceCacheTest.javaEnsures enrichment cache identity includes context snippets.
src/test/java/com/williamcallahan/javachat/service/ComprehensiveListFormattingTest.javaAdds regression test for abbreviation + trailing prose formatting.
src/test/java/com/williamcallahan/javachat/domain/markdown/MarkdownEnrichmentTest.javaVerifies Unicode-blank rejection across all permitted enrichment variants.
src/test/java/com/williamcallahan/javachat/config/SystemPromptConfigTest.javaAligns tests with AppProperties-owned docs JDK version binding.
src/test/java/com/williamcallahan/javachat/config/RequiredCredentialValidationTest.javaUpdates validation expectations to provider-selected credential checks.
src/main/resources/application.propertiesRemoves implicit OpenAI key fallback from GitHub Models compatibility client; updates docs/comments.
src/main/resources/application-dev.propertiesMirrors provider-selection/no-fallback guidance in dev profile docs.
src/main/java/com/williamcallahan/javachat/web/SseSupport.javaMoves accumulation after bounded buffering; removes streaming-notice projection; trims SSE payload contract fields.
src/main/java/com/williamcallahan/javachat/web/SseConstants.javaRemoves provider-fallback status code constant now that fallback is removed.
src/main/java/com/williamcallahan/javachat/web/GuidedLearningController.javaRemoves streaming notice events; sanitizes slug in exception message.
src/main/java/com/williamcallahan/javachat/web/ChatStreamRequest.javaEnforces canonical latest query and removes legacy message support.
src/main/java/com/williamcallahan/javachat/web/ChatController.javaSwitches to canonical latest query; removes runtime streaming notice merge.
src/main/java/com/williamcallahan/javachat/service/StreamingResult.javaSimplifies StreamingResult to (textChunks, provider) only.
src/main/java/com/williamcallahan/javachat/service/StreamingNoticeOrigin.javaDeletes notice-origin model no longer needed without fallback.
src/main/java/com/williamcallahan/javachat/service/StreamingNotice.javaDeletes streaming-notice model no longer needed without fallback.
src/main/java/com/williamcallahan/javachat/service/StreamingAttemptContext.javaDeletes provider-attempt context no longer needed without fallback.
src/main/java/com/williamcallahan/javachat/service/RetrievalService.javaUpdates citation identity to preserve final anchors for resolvable sources.
src/main/java/com/williamcallahan/javachat/service/RerankerService.javaEnforces strict JSON-only, permutation-only rerank ordering; forbids coercions and trailing tokens.
src/main/java/com/williamcallahan/javachat/service/RateLimitState.javaMakes rate-limit window evaluation atomic and concurrency-safe.
src/main/java/com/williamcallahan/javachat/service/RateLimitService.javaAdds request reservation API; uses circuit+daily admission checks consistently.
src/main/java/com/williamcallahan/javachat/service/ProviderCircuitState.javaAdds daily-window reservation logic with deterministic time injection and atomic reset.
src/main/java/com/williamcallahan/javachat/service/OpenAiRequestFactory.javaAdds eager startup validation + strict reasoning-effort parsing (known values only).
src/main/java/com/williamcallahan/javachat/service/OpenAiProviderCandidate.javaUpdates docs to reflect non-fallback semantics.
src/main/java/com/williamcallahan/javachat/service/markdown/MarkdownNormalizer.javaImproves list/fence indentation rules with CommonMark fence indentation limits.
src/main/java/com/williamcallahan/javachat/service/markdown/InlineListParser.javaPrevents abbreviation periods from prematurely terminating last list items.
src/main/java/com/williamcallahan/javachat/service/markdown/EnrichmentPlaceholderizer.javaDiscards Unicode-blank enrichment markers and improves fence/inline-code tracking.
src/main/java/com/williamcallahan/javachat/service/markdown/CodeFenceStateTracker.javaRefactors to explicit fence transitions and backtick-run inline-code tracking.
src/main/java/com/williamcallahan/javachat/service/ingestion/LocalDocsFileIngestionProcessor.javaUses shared Java API URL classifier for local ingestion structured extraction selection.
src/main/java/com/williamcallahan/javachat/service/ingestion/JavaPackageExtractor.javaCentralizes Java API URL classification and reuses it for package extraction.
src/main/java/com/williamcallahan/javachat/service/FileOperationsService.javaRemoves replacement-decoding fallback and enforces UTF-8 strict reads.
src/main/java/com/williamcallahan/javachat/service/EnrichmentService.javaSwitches to JSON-object completion boundary and strict JSON parsing + safer cache keying.
src/main/java/com/williamcallahan/javachat/service/DocsIngestionService.javaUses shared Java API classifier for remote ingestion extraction choice.
src/main/java/com/williamcallahan/javachat/service/ConfiguredProviderTemporarilyUnavailableException.javaAdds typed exception for “configured provider temporarily unavailable” admission failures.
src/main/java/com/williamcallahan/javachat/domain/markdown/Warning.javaUses Unicode-blank-aware blank detection for enrichment validation.
src/main/java/com/williamcallahan/javachat/domain/markdown/Reminder.javaUses Unicode-blank-aware blank detection for enrichment validation.
src/main/java/com/williamcallahan/javachat/domain/markdown/MarkdownEnrichment.javaIntroduces Unicode-blank-aware blank detection helper.
src/main/java/com/williamcallahan/javachat/domain/markdown/Hint.javaUses Unicode-blank-aware blank detection for enrichment validation.
src/main/java/com/williamcallahan/javachat/domain/markdown/Example.javaUses Unicode-blank-aware blank detection for enrichment validation.
src/main/java/com/williamcallahan/javachat/domain/markdown/Background.javaUses Unicode-blank-aware blank detection for enrichment validation.
src/main/java/com/williamcallahan/javachat/config/SystemPromptConfig.javaBinds prompt JDK version to AppProperties and uses placeholder replacement.
src/main/java/com/williamcallahan/javachat/config/RequiredCredentialValidation.javaValidates provider-selected credential availability at startup.
src/main/java/com/williamcallahan/javachat/config/ApiKeyLoggingConfig.javaLogs startup diagnostics based on configured provider selection (no fallback language).
README.mdUpdates toolchain/vendor guidance and provider selection instructions.
frontend/src/lib/validation/schemas.tsUpdates SSE event schema to remove fallback fields and support provider event.
frontend/src/lib/utils/url.tsFixes PDF classification/labels when query/fragment present; safer display filename decoding.
frontend/src/lib/utils/url.test.tsAdds PDF query/fragment/encoding coverage and hostname normalization checks.
frontend/src/lib/services/sse.test.tsUpdates status payload expectations; adds provider event dispatch coverage.
frontend/src/lib/services/markdown.tsAvoids rendering enrichment cards for empty content; returns escaped text on parse failures.
frontend/src/lib/services/markdown.test.tsAdds Unicode-blank enrichment rendering regression coverage.
frontend/src/lib/services/guided.tsForwards provider event callback through guided streaming.
frontend/src/lib/services/guided.test.tsUpdates terminal failure test; adds provider event forwarding coverage.
frontend/src/lib/services/chat.tsForwards provider event callback through chat streaming.
frontend/src/lib/services/chat.test.tsAdds provider event forwarding coverage.
frontend/src/lib/composables/createStreamingState.svelte.tsTracks selected provider separately and composes status details consistently.
frontend/src/lib/components/MessageBubble.test.tsPrevents Unicode-blank enrichment from appearing as fallback literal marker text.
frontend/src/lib/components/LearnView.svelteCancels/guards in-flight streams on unmount and lesson changes; captures provider event.
frontend/src/lib/components/CitationPanel.test.tsEnsures decoded PDF labels don’t change href/anchors.
frontend/src/lib/components/ChatView.test.tsAdds abort/unmount and stale-callback isolation tests; adds provider display checks.
frontend/src/lib/components/ChatView.svelteAdds abort controllers + stale-callback guards; shows selected provider via shared streaming state.
frontend/src/lib/components/AssistantMarkdownBody.svelteRemoves raw-text fallback branch in favor of consistent rendered HTML path.
docs/retrieval-pipeline.mdUpdates reranker parsing documentation to strict JSON/permutation requirements.
docs/pipeline-commands.mdUpdates doc-set filtering and Java API seed/manifest guidance; clarifies Qdrant init behavior.
docs/getting-started.mdUpdates setup to require selecting one provider + matching credential.
docs/configuration.mdUpdates provider selection/no-fallback contract and reasoning-effort validation guidance.
docs/api.mdDocuments new provider SSE event type.
DockerfileSwitches backend build/runtime images to pinned Liberica.
CONTRIBUTING.mdUpdates deterministic toolchain guidance to Liberica and pinning approach.
build.gradle.ktsPins toolchain vendor to BellSoft.
.tool-versionsPins Java tool version to Liberica 25.0.3+11.
.github/workflows/build.ymlUses Liberica distribution + .tool-versions pin in CI.
.env.exampleUpdates to “select one provider” configuration and removes fallback language.
.config/lefthook.ymlPrevents oxfmt from formatting Svelte files; limits formatting to JS/TS.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadfrontend/src/lib/components/ChatView.svelte
Comment threadfrontend/src/lib/components/ChatView.svelte
Comment threaddocs/api.md Outdated
Comment threaddocs/api.md Outdated

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:7891408331

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🧹 Nitpick comments (4)
src/test/java/com/williamcallahan/javachat/service/markdown/InlineListParserTest.java (1)

182-196: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace the newly introduced generic collection names with domain-specific roles.

  • src/test/java/com/williamcallahan/javachat/service/markdown/InlineListParserTest.java#L182-L196: rename lastItemTexts to lastListLabels.
  • src/test/java/com/williamcallahan/javachat/service/RerankerServiceTest.java#L75-L86: rename invalidOrderingJsonValues to malformedRerankJsonCases.

As per coding guidelines, generic nouns such as item and value, including close variants, are prohibited.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/test/java/com/williamcallahan/javachat/service/markdown/InlineListParserTest.java`
around lines 182 - 196, The collection in InlineListParserTest.java lines
182-196 should use the domain-specific name lastListLabels instead of
lastItemTexts. In RerankerServiceTest.java lines 75-86, rename
invalidOrderingJsonValues to malformedRerankJsonCases; update all references
while preserving the existing test behavior.

Source: Coding guidelines

src/main/java/com/williamcallahan/javachat/web/ChatController.java (1)

180-185: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Let SseSupport own the event-ordering recipe.

Both controllers now independently encode the same provider → status → data/heartbeat → citation protocol. A shared composition method would keep future event additions from becoming an exciting game of “spot the drift.”

  • src/main/java/com/williamcallahan/javachat/web/ChatController.java#L180-L185: replace the local Flux.concat sequence with the shared protocol method.
  • src/main/java/com/williamcallahan/javachat/web/GuidedLearningController.java#L302-L307: use that same method for guided streams.

As per coding guidelines, governed behavior must have one semantic owner, and duplicated logic should be reused.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/williamcallahan/javachat/web/ChatController.java` around
lines 180 - 185, Move the shared provider → status → data/heartbeat → citation
composition into an appropriate method on SseSupport, then replace the local
Flux.concat recipes in ChatController and GuidedLearningController with calls to
that method. Update
src/main/java/com/williamcallahan/javachat/web/ChatController.java:180-185 and
src/main/java/com/williamcallahan/javachat/web/GuidedLearningController.java:302-307;
preserve the existing event ordering and stream behavior.

Source: Coding guidelines

src/test/java/com/williamcallahan/javachat/service/OpenAIStreamingServiceTest.java (1)

52-63: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Name the configured-provider backoff once.

These 600 literals encode one test policy. A named constant prevents the scenarios from quietly drifting apart.

♻️ Proposed cleanup
 class OpenAIStreamingServiceTest {
+ private static final long CONFIGURED_PROVIDER_BACKOFF_SECONDS = 600;- new OpenAiProviderRoutingService(rateLimitService, 600, configuredProvider.getName());+ new OpenAiProviderRoutingService(+ rateLimitService, CONFIGURED_PROVIDER_BACKOFF_SECONDS, configuredProvider.getName());

Apply the same replacement to the remaining routing-service constructions.

As per coding guidelines, “No inline numbers (except 0, 1, -1) or strings; define named constants.” <coding_guidelines>

Also applies to: 92-99, 265-274, 300-310, 372-382

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/test/java/com/williamcallahan/javachat/service/OpenAIStreamingServiceTest.java`
around lines 52 - 63, Define a named constant for the configured-provider
backoff value of 600 in OpenAIStreamingServiceTest, then replace every
corresponding inline 600 in the test scenarios and remaining routing-service
constructions. Use that constant consistently while preserving the existing
backoff behavior.

Source: Coding guidelines

src/main/java/com/williamcallahan/javachat/service/ConfiguredProviderTemporarilyUnavailableException.java (1)

19-22: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove redundant null check.

Fun tidbit: Since messageFor() is evaluated first as part of the super() call, it already checks and guarantees that provider is not null! You can safely skip the second requireNonNull check in the constructor body to keep things slightly cleaner. 🚀

✨ Proposed refactor
 ConfiguredProviderTemporarilyUnavailableException(RateLimitService.ApiProvider provider) {
super(messageFor(provider));
- this.provider = Objects.requireNonNull(provider, "provider");+ this.provider = provider;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/com/williamcallahan/javachat/service/ConfiguredProviderTemporarilyUnavailableException.java`
around lines 19 - 22, Remove the redundant Objects.requireNonNull call from the
ConfiguredProviderTemporarilyUnavailableException constructor and assign
provider directly after the super(messageFor(provider)) call, relying on
messageFor’s existing null validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.config/lefthook.yml:
- Line 10: Update the frontend format hook’s glob in .config/lefthook.yml to
include .svelte files alongside JavaScript and TypeScript files, ensuring staged
Svelte files are processed by the existing formatting command.
In `@frontend/src/lib/services/markdown.ts`:
- Around line 389-400: Update the diagnostic warning in the hasFences &&
!isBalanced branch to avoid logging enrichment or raw token contents. Retain the
kind field, and replace content and raw with bounded metadata such as their
lengths, keeping the existing development-only warning behavior unchanged.
In `@src/main/java/com/williamcallahan/javachat/service/EnrichmentService.java`:
- Around line 22-25: Move ENRICHMENT_TEMPERATURE and
ENRICHMENT_OUTPUT_TOKEN_BUDGET out of EnrichmentService and into AppProperties
as bound configuration fields, with defaults defined in the appropriate Spring
property files. Inject AppProperties into EnrichmentService and use its values
when configuring enrichment generation; do not add environment-variable handling
or retain hard-coded LLM settings.
In
`@src/main/java/com/williamcallahan/javachat/service/ExternalServiceHealth.java`:
- Around line 341-372: The health-check state flow around tryStartCheck,
markHealthy, markUnhealthy, and reset must reject completions from obsolete
checks. Add a generation/token to ServiceHealthState, have tryStartCheck return
or record the token for the started check, and require markHealthy/markUnhealthy
to update via CAS only when that token still matches the active check; ensure
reset advances the generation so in-flight callbacks cannot clear or overwrite
the newer check.
In
`@src/main/java/com/williamcallahan/javachat/service/ingestion/JavaPackageExtractor.java`:
- Around line 27-29: Update JavaPackageExtractor.isJavaApiUrl and extractPackage
to parse the URL and match JAVA_API_PATH_SEGMENT only against the parsed path,
excluding query and fragment content. Reuse the parsed-path result where
appropriate, preserve existing package extraction behavior for valid API URLs,
and add regression coverage for query or fragment values containing “/api/”.
In
`@src/main/java/com/williamcallahan/javachat/service/markdown/MarkdownNormalizer.java`:
- Around line 105-107: Update the first-pass normalization logic in
MarkdownNormalizer, around fenceTracker and
scanFenceMarkerAtCommonMarkIndentation, to recognize opening and closing fences
with zero to three leading spaces before rewriting lines. Ensure indented fenced
content remains untouched throughout the first pass, while preserving the
existing second-pass scanner behavior.
In
`@src/main/java/com/williamcallahan/javachat/service/ProviderCircuitState.java`:
- Around line 60-65: Update ProviderCircuitState.recordSuccess() so a late
success cannot clear a circuit opened by a newer rate-limit outcome. Preserve
circuitOpen while the current nextRetryTime deadline has not elapsed, or use
reservation/version tracking so only the latest outcome may close the circuit;
retain reset behavior once the circuit is no longer within its retry window.
In
`@src/main/java/com/williamcallahan/javachat/support/RetrievalErrorClassifier.java`:
- Around line 64-80: The classify method in RetrievalErrorClassifier must
recognize HTTP 503/service-unavailable failures as a retryable category instead
of UNKNOWN. Add a 503 or service-unavailable matching branch that returns the
existing retryable category used by the retry path, and add a regression test
confirming Qdrant HTTP 503 failures are classified accordingly.
In `@src/main/resources/application.properties`:
- Around line 34-36: Update the GitHub Models compatibility properties so
spring.ai.openai.api-key and spring.ai.openai.chat.api-key are sourced directly
from the process environment without blank defaults, and configure the GitHub
Models base URL from its environment variable. Keep this client restricted to
the GitHub Models provider rather than allowing an alternate provider URL.
In
`@src/test/java/com/williamcallahan/javachat/service/EnrichmentServiceTest.java`:
- Around line 33-38: Update EnrichmentServiceTest.setUp to use the
Spring-managed ObjectMapper from the focused test configuration established by
EnrichmentServiceCacheTest instead of manually constructing a new ObjectMapper.
Inject or autowire that mapper and pass it to EnrichmentService while preserving
the existing OpenAIStreamingService mock setup.
In
`@src/test/java/com/williamcallahan/javachat/service/OpenAiRequestFactoryTest.java`:
- Around line 33-46: Update invalidReasoningEffortFailsLazyApplicationStartup to
configure the reasoning-effort value through the canonical custom app.* Spring
property bound by AppProperties, rather than the prohibited
OPENAI_REASONING_EFFORT command-line key. Ensure the default is defined in the
appropriate Spring property files and start the test with the canonical property
key while preserving the existing invalid-value assertion.
---
Nitpick comments:
In
`@src/main/java/com/williamcallahan/javachat/service/ConfiguredProviderTemporarilyUnavailableException.java`:
- Around line 19-22: Remove the redundant Objects.requireNonNull call from the
ConfiguredProviderTemporarilyUnavailableException constructor and assign
provider directly after the super(messageFor(provider)) call, relying on
messageFor’s existing null validation.
In `@src/main/java/com/williamcallahan/javachat/web/ChatController.java`:
- Around line 180-185: Move the shared provider → status → data/heartbeat →
citation composition into an appropriate method on SseSupport, then replace the
local Flux.concat recipes in ChatController and GuidedLearningController with
calls to that method. Update
src/main/java/com/williamcallahan/javachat/web/ChatController.java:180-185 and
src/main/java/com/williamcallahan/javachat/web/GuidedLearningController.java:302-307;
preserve the existing event ordering and stream behavior.
In
`@src/test/java/com/williamcallahan/javachat/service/markdown/InlineListParserTest.java`:
- Around line 182-196: The collection in InlineListParserTest.java lines 182-196
should use the domain-specific name lastListLabels instead of lastItemTexts. In
RerankerServiceTest.java lines 75-86, rename invalidOrderingJsonValues to
malformedRerankJsonCases; update all references while preserving the existing
test behavior.
In
`@src/test/java/com/williamcallahan/javachat/service/OpenAIStreamingServiceTest.java`:
- Around line 52-63: Define a named constant for the configured-provider backoff
value of 600 in OpenAIStreamingServiceTest, then replace every corresponding
inline 600 in the test scenarios and remaining routing-service constructions.
Use that constant consistently while preserving the existing backoff behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1bf281e4-65b9-48f4-a5ee-74575e85114e

📥 Commits

Reviewing files that changed from the base of the PR and between c9bf79e and 7891408.

📒 Files selected for processing (102)
  • .config/lefthook.yml
  • .env.example
  • .github/workflows/build.yml
  • .tool-versions
  • CONTRIBUTING.md
  • Dockerfile
  • README.md
  • build.gradle.kts
  • docs/api.md
  • docs/configuration.md
  • docs/development.md
  • docs/getting-started.md
  • docs/pipeline-commands.md
  • docs/retrieval-pipeline.md
  • frontend/src/lib/components/AssistantMarkdownBody.svelte
  • frontend/src/lib/components/ChatView.svelte
  • frontend/src/lib/components/ChatView.test.ts
  • frontend/src/lib/components/CitationPanel.test.ts
  • frontend/src/lib/components/LearnView.svelte
  • frontend/src/lib/components/LearnView.test.ts
  • frontend/src/lib/components/MessageBubble.test.ts
  • frontend/src/lib/composables/createStreamingState.svelte.ts
  • frontend/src/lib/services/chat.test.ts
  • frontend/src/lib/services/chat.ts
  • frontend/src/lib/services/guided.test.ts
  • frontend/src/lib/services/guided.ts
  • frontend/src/lib/services/markdown.test.ts
  • frontend/src/lib/services/markdown.ts
  • frontend/src/lib/services/sse.test.ts
  • frontend/src/lib/utils/url.test.ts
  • frontend/src/lib/utils/url.ts
  • frontend/src/lib/validation/schemas.ts
  • src/main/java/com/williamcallahan/javachat/config/ApiKeyLoggingConfig.java
  • src/main/java/com/williamcallahan/javachat/config/RequiredCredentialValidation.java
  • src/main/java/com/williamcallahan/javachat/config/SystemPromptConfig.java
  • src/main/java/com/williamcallahan/javachat/domain/markdown/Background.java
  • src/main/java/com/williamcallahan/javachat/domain/markdown/Example.java
  • src/main/java/com/williamcallahan/javachat/domain/markdown/Hint.java
  • src/main/java/com/williamcallahan/javachat/domain/markdown/MarkdownEnrichment.java
  • src/main/java/com/williamcallahan/javachat/domain/markdown/Reminder.java
  • src/main/java/com/williamcallahan/javachat/domain/markdown/Warning.java
  • src/main/java/com/williamcallahan/javachat/service/ConfiguredProviderTemporarilyUnavailableException.java
  • src/main/java/com/williamcallahan/javachat/service/DocsIngestionService.java
  • src/main/java/com/williamcallahan/javachat/service/EnrichmentService.java
  • src/main/java/com/williamcallahan/javachat/service/ExternalServiceHealth.java
  • src/main/java/com/williamcallahan/javachat/service/FileOperationsService.java
  • src/main/java/com/williamcallahan/javachat/service/OpenAIStreamingService.java
  • src/main/java/com/williamcallahan/javachat/service/OpenAiProviderCandidate.java
  • src/main/java/com/williamcallahan/javachat/service/OpenAiProviderRoutingService.java
  • src/main/java/com/williamcallahan/javachat/service/OpenAiRequestFactory.java
  • src/main/java/com/williamcallahan/javachat/service/ProviderCircuitState.java
  • src/main/java/com/williamcallahan/javachat/service/RateLimitService.java
  • src/main/java/com/williamcallahan/javachat/service/RateLimitState.java
  • src/main/java/com/williamcallahan/javachat/service/RerankerService.java
  • src/main/java/com/williamcallahan/javachat/service/RetrievalService.java
  • src/main/java/com/williamcallahan/javachat/service/StreamingAttemptContext.java
  • src/main/java/com/williamcallahan/javachat/service/StreamingNotice.java
  • src/main/java/com/williamcallahan/javachat/service/StreamingNoticeOrigin.java
  • src/main/java/com/williamcallahan/javachat/service/StreamingResult.java
  • src/main/java/com/williamcallahan/javachat/service/ingestion/JavaPackageExtractor.java
  • src/main/java/com/williamcallahan/javachat/service/ingestion/LocalDocsFileIngestionProcessor.java
  • src/main/java/com/williamcallahan/javachat/service/markdown/CodeFenceStateTracker.java
  • src/main/java/com/williamcallahan/javachat/service/markdown/EnrichmentPlaceholderizer.java
  • src/main/java/com/williamcallahan/javachat/service/markdown/InlineListParser.java
  • src/main/java/com/williamcallahan/javachat/service/markdown/MarkdownNormalizer.java
  • src/main/java/com/williamcallahan/javachat/support/RetrievalErrorClassifier.java
  • src/main/java/com/williamcallahan/javachat/web/ChatController.java
  • src/main/java/com/williamcallahan/javachat/web/ChatStreamRequest.java
  • src/main/java/com/williamcallahan/javachat/web/GuidedLearningController.java
  • src/main/java/com/williamcallahan/javachat/web/SseConstants.java
  • src/main/java/com/williamcallahan/javachat/web/SseSupport.java
  • src/main/resources/application-dev.properties
  • src/main/resources/application.properties
  • src/test/java/com/williamcallahan/javachat/config/RequiredCredentialValidationTest.java
  • src/test/java/com/williamcallahan/javachat/config/SystemPromptConfigTest.java
  • src/test/java/com/williamcallahan/javachat/domain/markdown/MarkdownEnrichmentTest.java
  • src/test/java/com/williamcallahan/javachat/service/ComprehensiveListFormattingTest.java
  • src/test/java/com/williamcallahan/javachat/service/EnrichmentServiceCacheTest.java
  • src/test/java/com/williamcallahan/javachat/service/EnrichmentServiceTest.java
  • src/test/java/com/williamcallahan/javachat/service/ExternalServiceHealthTest.java
  • src/test/java/com/williamcallahan/javachat/service/OpenAIStreamingServiceTest.java
  • src/test/java/com/williamcallahan/javachat/service/OpenAiProviderRoutingServiceTest.java
  • src/test/java/com/williamcallahan/javachat/service/OpenAiRequestFactoryTest.java
  • src/test/java/com/williamcallahan/javachat/service/ProviderCircuitStateTest.java
  • src/test/java/com/williamcallahan/javachat/service/RateLimitStateTest.java
  • src/test/java/com/williamcallahan/javachat/service/RerankerServiceTest.java
  • src/test/java/com/williamcallahan/javachat/service/RetrievalServiceTest.java
  • src/test/java/com/williamcallahan/javachat/service/StreamingAttemptContextTest.java
  • src/test/java/com/williamcallahan/javachat/service/ingestion/LocalDocsFileIngestionProcessorTest.java
  • src/test/java/com/williamcallahan/javachat/service/ingestion/MalformedUtf8LocalDocsIngestionTest.java
  • src/test/java/com/williamcallahan/javachat/service/markdown/EnrichmentPlaceholderizerTest.java
  • src/test/java/com/williamcallahan/javachat/service/markdown/InlineListParserTest.java
  • src/test/java/com/williamcallahan/javachat/service/markdown/MarkdownFenceRenderingTest.java
  • src/test/java/com/williamcallahan/javachat/service/markdown/MarkdownNormalizerTest.java
  • src/test/java/com/williamcallahan/javachat/support/RetrievalErrorClassifierTest.java
  • src/test/java/com/williamcallahan/javachat/web/ChatControllerStreamingFailureTest.java
  • src/test/java/com/williamcallahan/javachat/web/ChatStreamRequestTest.java
  • src/test/java/com/williamcallahan/javachat/web/GuidedLearningControllerStreamingFailureTest.java
  • src/test/java/com/williamcallahan/javachat/web/GuidedLearningControllerTest.java
  • src/test/java/com/williamcallahan/javachat/web/GuidedSseCitationEventTest.java
  • src/test/java/com/williamcallahan/javachat/web/SseSupportTest.java
  • src/test/java/com/williamcallahan/javachat/web/StreamingProviderFallbackSseEventTest.java
💤 Files with no reviewable changes (7)
  • src/test/java/com/williamcallahan/javachat/service/StreamingAttemptContextTest.java
  • src/main/java/com/williamcallahan/javachat/service/StreamingNoticeOrigin.java
  • src/main/java/com/williamcallahan/javachat/web/SseConstants.java
  • src/main/java/com/williamcallahan/javachat/service/StreamingNotice.java
  • src/main/java/com/williamcallahan/javachat/service/StreamingAttemptContext.java
  • src/test/java/com/williamcallahan/javachat/web/StreamingProviderFallbackSseEventTest.java
  • frontend/src/lib/validation/schemas.ts

Comment thread.config/lefthook.yml
Comment threadfrontend/src/lib/services/markdown.ts Outdated
Comment threadsrc/main/java/com/williamcallahan/javachat/service/EnrichmentService.java Outdated
Comment threadsrc/main/resources/application.properties Outdated
…st-marker-detection-references-in-pa-6c87a0
docs: update list marker detection references in parsing docs
…ient-side-markdown-processing-for-sv-107ab3
docs: update client-side markdown processing for Svelte frontend
…ng-sse-provider-event-and-full-statu-65a6b2
docs: add missing SSE provider event and full status/error field shapes

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/domains/all-parsing-and-markdown-logic.md`:
- Around line 143-172: Replace the detailed “Svelte Frontend Markdown
Processing” implementation summary with a responsibility-level architecture
description and links to the canonical frontend documentation or source files.
Remove mirrored file paths, function names, parser-mode details, and rendering
behavior from this document, or generate the section from the canonical owners
so it cannot drift.
- Around line 281-283: Reconcile the Svelte architecture description with the
retained legacy references in the sections around markdown-utils.js,
/render/structured, and chat.html. Clearly label those paragraphs as
historical/legacy and identify the server-authoritative Svelte pipeline as
current, or remove obsolete details so the document presents one unambiguous
authoritative flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e37a4252-7810-4ac8-8d27-f9a349551d37

📥 Commits

Reviewing files that changed from the base of the PR and between 7891408 and 4d674b3.

📒 Files selected for processing (3)
  • docs/api.md
  • docs/domains/all-parsing-and-markdown-logic.md
  • frontend/src/lib/services/markdown.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/api.md
  • frontend/src/lib/services/markdown.ts

Comment threaddocs/domains/all-parsing-and-markdown-logic.md Outdated
Comment threaddocs/domains/all-parsing-and-markdown-logic.md Outdated
Documentation fetchers, Java catalog readers, and ingestion markers previously restated source identities and extraction behavior. The canonical manifest now drives every projection and semantic versioning forces stale documents to reindex.
- Project Java and shell catalogs from one manifest
- Version local ingestion markers by extractor semantics
- Classify Java API sources by manifest-backed URI paths
Every table-of-contents lesson now has curated, packaged content, so navigation cannot land on a lesson whose source is missing at runtime.
- Add nine complete lesson resources
- Verify every lesson slug resolves to meaningful content
- Exclude local curation scratch work from version control
Enrichment kinds could diverge across Java, frontend, prompts, and styles, while incomplete streams could misread code fences as marker boundaries. Every consumer now projects one manifest and both parsers honor CommonMark code regions.
- Replace five mirrored domain variants with one manifest-backed record
- Protect 0-3 space fences, indented code, and multiline backticks
- Reject invisible-only markers and emit bounded development diagnostics
Replaced or overloaded streams could mutate current lesson state, and bounded overflow could expose partial text without a terminal contract. Request ownership now survives every await and all failed streams end consistently without persistence.
- Abort stale citation and lesson work across replacement and teardown
- Fail bounded SSE overflow with a retryable terminal error
- Share configured-provider cooldown handling across chat modes
Generation knobs and embedding credentials had multiple owners, allowing startup behavior and scripts to disagree. Non-secret policy now binds through typed application properties while credentials enter only through approved environment variables.
- Centralize chat, enrichment, and reranker generation settings
- Bind Qdrant and embedding secrets directly from the environment
- Remove unused Spring AI chat auto-configuration
Readiness alone could not distinguish a fresh deployment from a healthy stale container. The public sanitized build-info endpoint and Docker smoke now require both build identities to match the source commit.
- Expose only actuator health and sanitized info publicly
- Assert deployment and build commits in the container smoke job
- Document the complete single-provider SSE contract
Merge the reviewed remote dev documentation commits without rewriting local history. Conflict resolution preserves the current single-provider SSE schema, strict reranker contract, and canonical Spring Framework selector while retaining the accepted README, CI, and parsing documentation corrections.
The focused cache context constructs AppProperties without Spring Boot property binding, so it must provide the same non-secret embedding settings that production receives from application.properties.
Serialize shared build outputs with a kernel-managed lock and keep quality gates strict.
Eliminate JDK, Mockito, Oxlint, static-analysis, and expected negative-path log noise.
@WilliamAGHWilliamAGH changed the title fix(chat): configured-provider routing, stale-stream isolation, and strict response contractsfeat(platform): complete guided learning and harden streaming, ingestion, and deploysJul 18, 2026
The non-secret Novita endpoint and model were removed from deployment ownership while the credential remained active, causing the new container to fail startup. Bind those settings from application properties, keep runtime and ingestion provider selection aligned, and cover the deployed configuration shape with startup tests.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugSomething isn't workingdocumentationImprovements or additions to documentationenhancementNew feature or requestjavaPull requests that update java codejavascriptPull requests that update javascript coderefactorCode refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@WilliamAGH