No-QA generation runs and TEI-P5 retrieval (4.3.2) - #141
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (11)
🔗 Linked repositories identifiedCodeRabbit considers these linked repositories for cross-repo context during reviews:
Included review availability: 4 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour. SummaryImplement durable no-QA generation runs and TEI-P5 retrieval.
Document the implementation in ADR-017 and the completed ExecPlan. Update the developer, user, system design, repository layout, contents, and roadmap documentation. WalkthroughAdd a no-QA generation-run slice. Define durable run and event storage, draft generation, TEI revision persistence, authenticated REST endpoints, ownership rules, runtime configuration, tracing and metrics, and broad test and document updates. ChangesNo-QA generation slice
Suggested labels: Poem
Merge Risk: 🟡 Moderate · up to This PR adds durable no-QA generation runs and TEI retrieval, allowing clients to start runs and consume generated documents. Merge readiness is currently moderate because the public run contract rejects values it declares as defaulted and required quality gates are still failing; shutdown failure paths can also leave resources undisposed until these issues are fixed or explicitly accepted. Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error, 4 warnings)
✅ Passed checks (15 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
c5422af to
0d648a9
Compare
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Excess Number of Function Argumentstests/test_generation_run_port_contract.py: NoopGenerationRunPort.update_run_status has 6 arguments, max arguments = 4 Why does this problem occur?Functions with many arguments indicate either a) low cohesion where the function has too many responsibilities, or b) a missing abstraction that encapsulates those arguments. How to fix it?Start by investigating the responsibilities of the function. Make sure it doesn't do too many things, in which case it should be split into smaller and more cohesive functions. Consider the refactoring INTRODUCE PARAMETER OBJECT to encapsulate arguments that refer to the same logical concept. Overall Code Complexityepisodic/canonical/adapters/generation_runs.py: What lead to degradation?This module has a mean cyclomatic complexity of 4.10 across 10 functions. The mean complexity threshold is 4 Why does this problem occur?Overall Code Complexity is measured by the mean cyclomatic complexity across all functions in the file. The lower the number, the better. How to fix it?You address the overall cyclomatic complexity by a) modularizing the code, and b) abstract away the complexity. Let's look at some examples: |
This comment was marked as resolved.
This comment was marked as resolved.
34d6f58 to
a3d64bb
Compare
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. episodic/canonical/adapters/generation_runs.py Comment on file from episodic.canonical.domain import (
Checkpoint,
CheckpointResponse,❌ New issue: Overall Code Complexity |
This comment was marked as resolved.
This comment was marked as resolved.
94b189d to
e551b3a
Compare
There was a problem hiding this comment.
Sorry @leynos, your pull request is larger than the review limit of 150000 diff characters
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Overall Code Complexityepisodic/canonical/adapters/generation_runs.py: What lead to degradation?This module has a mean cyclomatic complexity of 4.18 across 11 functions. The mean complexity threshold is 4 Why does this problem occur?Overall Code Complexity is measured by the mean cyclomatic complexity across all functions in the file. The lower the number, the better. How to fix it?You address the overall cyclomatic complexity by a) modularizing the code, and b) abstract away the complexity. Let's look at some examples: |
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message in a code block that I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. episodic/canonical/storage/generation_runs.py Comment on lines +303 to +319 async def list_events(
self,
run_id: uuid.UUID,
*,
after_seq: EventSeq | None = None,
limit: int = 100,
offset: int = 0,
) -> tuple[GenerationEvent, ...]:
"""List events for a run after an optional sequence cursor."""
if limit < 0 or offset < 0:
msg = "limit and offset must be non-negative."
raise ValueError(msg)
if after_seq is not None and offset != 0:
msg = "after_seq and offset cannot be combined."
raise ValueError(msg)
if await self._get_record(run_id) is None:
raise RunNotFound(run_id)❌ New issue: Complex Method |
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message in a code block that I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. episodic/canonical/adapters/generation_runs.py Comment on file *,
after_seq: EventSeq | None = None,
limit: int = 100,
offset: int = 0,❌ New issue: Complex Method |
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message in a code block that I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. tests/test_source_intake_api.py Comment on lines +54 to +58 dependencies = build_api_dependencies(
session_factory,
authorization=HeaderPrincipalAuthorization(),
object_store=object_store,
)❌ New issue: Large Method |
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message in a code block that I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. tests/test_source_intake_api_contract.py Comment on file """Contract tests for source-intake REST error paths and read endpoints."""
import contextlib❌ New issue: Code Duplication |
This comment was marked as resolved.
This comment was marked as resolved.
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message in a code block that I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. tests/test_source_intake_api_contract_support.py Comment on lines +91 to +113 async def _create_pending_upload(
session_factory: async_sessionmaker[AsyncSession],
) -> uuid.UUID:
"""Persist one pending upload for not-ready attach tests."""
now = dt.datetime.now(dt.UTC)
upload = Upload(
id=uuid.uuid4(),
owner_principal_id="principal-a",
content_type="text/plain",
declared_size=1,
actual_size=None,
declared_sha256=None,
content_hash=None,
storage_key=f"uploads/{uuid.uuid4()}",
state=UploadState.PENDING,
metadata={},
created_at=now,
updated_at=now,
)
async with SqlAlchemyUnitOfWork(session_factory) as uow:
await uow.uploads.add(upload)
await uow.commit()
return upload.id❌ New issue: Code Duplication |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
@coderabbitai Have the following now been resolved? episodic/api/runtime.py (1)
257 executes. This leaves provider-client connections open while shutdown continues with the remaining hooks. Proposed fixasync def shutdown_generation() -> None:
"""Stop generation work before closing its provider client."""
- await launcher.shutdown()
- await llm_port.aclose()
+ try:
+ await launcher.shutdown()
+ finally:
+ await llm_port.aclose()🤖 Detailed instructionsUse a wyvern agent team to verify each finding against the current code and only fix it if needed. Fix any documentation issues using a scribe agent team. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. Use a scrutineer agent for execution of tests and summarizing the results. In |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== Current revision =="
git rev-parse HEAD
echo
echo "== Runtime outline =="
ast-grep outline episodic/api/runtime.py --match 'shutdown_generation|create_app_from_env' --view expanded || true
echo
echo "== Shutdown implementation =="
rg -n -A45 -B15 \
'async def shutdown_generation\b|launcher\.shutdown\(\)|llm_port\.aclose\(\)' \
episodic/api/runtime.py
echo
echo "== Shutdown lifecycle tests and references =="
rg -n -A90 -B12 \
'shutdown_generation|launcher.*shutdown|aclose\(|shuts_down_generation|shutdown.*fail|RuntimeError' \
tests episodic/api -g '*.py'Length of output: 195307 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== Current revision =="
git rev-parse HEAD
echo
echo "== shutdown_generation source =="
rg -n -A24 -B8 'async def shutdown_generation\b' episodic/api/runtime.py
echo
echo "== All launcher/LLM shutdown ordering in runtime =="
rg -n -C4 'launcher\.shutdown\(\)|llm_port\.aclose\(\)|shutdown_hooks' episodic/api/runtime.py
echo
echo "== Runtime wiring test body =="
rg -n -A100 -B8 \
'^async def test_create_app_from_env_wires_configured_llm_launcher\b' \
tests/test_env_runtime_wiring.py
echo
echo "== Explicit regression tests for launcher failure plus LLM closure =="
rg -n -C5 \
'launcher shutdown failed|shutdown.*raises|aclose.*called|close.*launcher|Failing.*Launcher|_Failing.*Launcher' \
tests/test_env_runtime_wiring.py tests/test_lifespan_hooks.pyLength of output: 8086
episodic/api/runtime.py — Treat this finding as resolved at revision Lines 263-268 now use try:
await launcher.shutdown()
finally:
await llm_port.aclose()
The current runtime-wiring test covers the normal shutdown path. It does not simulate a You are interacting with an AI system. |
Add bounded API request metrics, durable scheduling-failure handling, and deterministic ingestion-job reservation timestamps. Refactor generation-event pagination and source-intake test fixtures while extending the associated contract, terminal-claim, property, and API failure coverage. Document the public generation-run and runtime contracts and keep the reflection-based Falcon middleware visible to the dead-code gate.
|
@coderabbitai review |
✅ Action performedReview finished.
|
Commit placeholder episode reservation only after source projection and verification succeed, so a missing upload cannot leave a reusable partial episode. Inject the API route metrics clock through `ApiDependencies` and correct launch-failure, persistence-port, and ADR contracts.
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message in a code block that I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. Code Duplicationtests/test_source_intake_api_contract_support.py: What lead to degradation?The module contains 2 functions with similar structure: _create_pending_upload,_create_ready_upload Why does this problem occur?Duplicated code often leads to code that's harder to change since the same logical change has to be done in multiple functions. More duplication gives lower code health. How to fix it?A certain degree of duplicated code might be acceptable. The problems start when it is the same behavior that is duplicated across the functions in the module, ie. a violation of the Don't Repeat Yourself (DRY) principle. DRY violations lead to code that is changed together in predictable patterns, which is both expensive and risky. DRY violations can be identified using CodeScene's X-Ray analysis to detect clusters of change coupled functions with high code similarity. Read More |
|
@coderabbitai Have the following now been resolved? episodic/api/resources/generation_runs.py (1)
with NumPy-style documentation. Define the request inputs, successful response, error responses, ownership rule, and idempotency requirement. comprehensive NumPy-style docstrings.” As per path instructions, “Docstrings must follow the numpy style guide ... for all public interfaces.” 🤖 Detailed instructionsUse a wyvern agent team to verify each finding against the current code and only fix it if needed. Fix any documentation issues using a scribe agent team. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. Use a scrutineer agent for execution of tests and summarizing the results. In Sources: Coding guidelines, Path instructions episodic/canonical/entity_protocols.py (1)
to the port and its SQLAlchemy implementation. State the and the zero-row behaviour for an unknown
contract for
port documentation and state that the SQL instructions, “Docstrings must follow the numpy style guide.” 🤖 Detailed instructionsUse a wyvern agent team to verify each finding against the current code and only fix it if needed. Fix any documentation issues using a scribe agent team. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. Use a scrutineer agent for execution of tests and summarizing the results. In Sources: Coding guidelines, Path instructions episodic/canonical/entity_protocols.py (1)
for an unrecognized persistence failure. The generic type prevents callers from implementing a reliable failure boundary. #!/bin/bash
set -euo pipefail
ast-grep outline episodic/canonical/storage/repositories.py \
--items all --type method --match 'add_projection' --view expanded
rg -n -C 8 'async def add_projection|IntegrityError|SourceDocumentProjectionResult' \
episodic/canonical/storage/repositories.py🤖 Detailed instructionsUse a wyvern agent team to verify each finding against the current code and only fix it if needed. Fix any documentation issues using a scribe agent team. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. Use a scrutineer agent for execution of tests and summarizing the results. In Source: Coding guidelines |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== CURRENT REVISION =="
git rev-parse HEAD
echo
echo "== TARGET MODULE OUTLINE =="
ast-grep outline tests/test_source_intake_api_contract_support.py --view expanded || true
echo
echo "== UPLOAD FIXTURE HELPERS =="
rg -n -A90 -B12 \
'^(async )?def (_create_pending_upload|_create_ready_upload|_create_upload)\b' \
tests/test_source_intake_api_contract_support.py
echo
echo "== HELPER CALL SITES =="
rg -n -C3 \
'\b(_create_pending_upload|_create_ready_upload|_create_upload)\s*\(' \
tests -g '*.py'
echo
echo "== PR-RELATIVE DIFF FOR TARGET =="
base="$(git merge-base HEAD origin/main 2>/dev/null || true)"
if [ -n "$base" ]; then
git diff --unified=12 "$base" HEAD -- tests/test_source_intake_api_contract_support.py
else
echo "No merge base with origin/main is available."
fi
echo
echo "== STRUCTURAL UPLOAD CONSTRUCTION COUNT =="
ast-grep run \
--pattern 'Upload($$$)' \
--lang python \
tests/test_source_intake_api_contract_support.py || trueLength of output: 11185
tests/test_source_intake_api_contract_support.py — Suppress this diagnostic. The finding is resolved in the current codegraph at revision
Do not apply another refactor. Further extraction would either merge distinct pending and ready fixture contracts or add indirection with no duplicated persistence logic to remove. Validated this diagnostic against the current PR codegraph at revision `68ea6f3f3ad492ace653158e061f575769c9c027`.
The duplicated upload-fixture implementation no longer exists. `tests/test_source_intake_api_contract_support.py` contains one shared `_create_upload` helper. That helper owns `Upload` construction, unit-of-work persistence, commit, and ID return. `_create_pending_upload` and `_create_ready_upload` are thin semantic wrappers. They only supply their distinct fixture values.
Suppress this diagnostic because further refactoring would not remove duplicated behaviour. It would either hide the pending and ready fixture contracts behind a less specific API or add unnecessary abstraction. Keep the wrappers because their names express the required test state at each call site.You are interacting with an AI system. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== Current revision =="
git rev-parse HEAD
echo
echo "== Target outlines =="
ast-grep outline episodic/api/resources/generation_runs.py \
--match 'GenerationRunsResource' --view expanded
ast-grep outline episodic/canonical/entity_protocols.py \
--match 'IngestionJobRepository|SourceDocumentRepository' --view expanded
ast-grep outline episodic/canonical/storage/ingestion_job_repositories.py \
--match 'SqlAlchemyIngestionJobRepository' --view expanded
ast-grep outline episodic/canonical/storage/repositories.py \
--match 'SqlAlchemySourceDocumentRepository' --view expanded
echo
echo "== GenerationRunsResource and on_post =="
rg -n -A230 -B12 \
'^class GenerationRunsResource\b|^ async def on_post\b' \
episodic/api/resources/generation_runs.py
echo
echo "== Port contracts =="
rg -n -A100 -B12 \
'^class IngestionJobRepository\b|^ async def set_target_episode\b|^class SourceDocumentRepository\b|^ async def add_projection\b' \
episodic/canonical/entity_protocols.py
echo
echo "== SQLAlchemy ingestion-job contract =="
rg -n -A80 -B12 \
'^class SqlAlchemyIngestionJobRepository\b|^ async def set_target_episode\b' \
episodic/canonical/storage/ingestion_job_repositories.py
echo
echo "== SQLAlchemy projection exception path =="
rg -n -A130 -B20 \
'^class SqlAlchemySourceDocumentRepository\b|^ async def add_projection\b|IntegrityError|is_source_document_duplicate_integrity_error' \
episodic/canonical/storage/repositories.py \
episodic/canonical/storage/integrity_helpers.py
echo
echo "== Relevant imports =="
sed -n '1,80p' episodic/canonical/entity_protocols.py
sed -n '1,70p' episodic/canonical/storage/repositories.pyLength of output: 68298
episodic/api/resources/generation_runs.py —
episodic/canonical/entity_protocols.py — Both docstrings now document episodic/canonical/entity_protocols.py — The port now names
You are interacting with an AI system. |
Summary
This implementation completes roadmap task 4.3.2 — No-QA generation runs
and TEI-P5 retrieval, the second half of the source-to-script REST vertical
slice defined in ADR 009.
The design and build phases are complete. The living ExecPlan records all
milestone decisions, discoveries, progress, and validation evidence:
docs/execplans/4-3-2-no-qa-generation-runs-and-tei-p5-retrieval.mdImplemented behaviour
An integration client can now:
quality_mode=draft_without_qa, a rationale,and actor metadata.
application/tei+xmlwith an ETagand attachment metadata.
Identical idempotent replays preserve the run id,
Location, andRetry-After; changed bodies conflict. Provider and TEI failures becomeclassified terminal run state.
Architecture
GenerationRunLauncherisolates scheduling from durable execution state; thefirst adapter runs in-process with bounded concurrency and shutdown draining.
persist through SQLAlchemy adapters and Alembic migrations.
DraftScriptGeneratorisolates the single-pass LLM draft policy from thelauncher and its future roadmap 4.4.1 successor.
recovery hooks, HTTP status choices, and content negotiation.
Validation
make check-fmtmake typecheckmake lint— Pylint 10.00/10make check-migrationsmake test— 1,076 passed, 1 skippedmake markdownlintmake nixievidaimock 0.1.3References
Summary by Sourcery
Deliver the no-QA source-to-script REST slice with durable generation runs, validated TEI-P5 persistence, authenticated polling, and content-negotiated retrieval.
New Features:
Bug Fixes:
Enhancements:
Build:
CI:
Documentation:
Tests: