Skip to content

module 2#147

Merged
wen-placeholder merged 2 commits into
fix/studio-output-dir-validation-p2c-designfrom
wenjing0224
Feb 26, 2026
Merged

module 2#147
wen-placeholder merged 2 commits into
fix/studio-output-dir-validation-p2c-designfrom
wenjing0224

Conversation

@wen-placeholder

Copy link
Copy Markdown
Collaborator

add module2 ReproContext pack DB, API, port and store. Related to #139

@vercel

vercel Bot commented Feb 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
paper-bot Ready Ready Preview, Comment Feb 26, 2026 9:38pm

@coderabbitai

coderabbitai Bot commented Feb 26, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch wenjing0224

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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 and usage tips.

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces 'Module 2' functionality, enabling Paper-to-Context (P2C) capabilities within the application. It establishes the foundational database structures, defines the necessary API endpoints, and implements the persistence layer to manage the lifecycle of reproduction context packs. This allows for the generation, storage, retrieval, and management of these context packs, facilitating the creation of reproduction sessions from research papers.

Highlights

  • New P2C Context Pack Database Schema: Introduced four new database tables: repro_context_pack to store the main context pack data, repro_context_stage_result for intermediate stage results, repro_context_evidence for linking extracted fields to paper spans, and repro_context_feedback for user ratings and comments.
  • P2C API Endpoints: Added a new set of API endpoints under /api/research/repro/context to manage P2C context packs. These endpoints support generating context packs (via Server-Sent Events), listing packs for a user, retrieving full pack details, creating reproduction sessions from packs, and soft-deleting packs.
  • ReproContext Persistence Layer: Defined a ReproContextPort protocol as an abstract interface for P2C context pack persistence operations and implemented it with SqlAlchemyReproContextStore for concrete database interactions.
  • API Integration: Integrated the new repro_context API router into the main FastAPI application, making the P2C functionality accessible.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • alembic/versions/b94c1a2be26e_add_p2c_repro_context_pack_tables.py
    • Added a new Alembic migration script to create four database tables: repro_context_pack, repro_context_stage_result, repro_context_evidence, and repro_context_feedback.
  • src/paperbot/api/main.py
    • Imported the new repro_context module.
    • Included the repro_context API router with a dedicated prefix and tag.
  • src/paperbot/api/routes/repro_context.py
    • Added a new file defining the P2C API routes for generating, listing, retrieving, creating sessions from, and soft-deleting context packs.
    • Implemented Server-Sent Events (SSE) for the context pack generation process.
  • src/paperbot/application/ports/repro_context_port.py
    • Added a new file defining the ReproContextPort protocol, an abstract interface for P2C context pack persistence.
  • src/paperbot/infrastructure/stores/models.py
    • Added four new SQLAlchemy models: ReproContextPackModel, ReproContextStageResultModel, ReproContextEvidenceModel, and ReproContextFeedbackModel to represent the P2C database entities.
  • src/paperbot/infrastructure/stores/repro_context_store.py
    • Added a new file implementing SqlAlchemyReproContextStore, providing the concrete persistence logic for P2C context packs using SQLAlchemy.
  • web/src/app/studio/page.tsx
    • Updated the main studio page's height calculation in CSS from calc(100vh - theme(spacing.16)) to h-screen.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@wen-placeholder
wen-placeholder merged commit 4978ac4 into fix/studio-output-dir-validation-p2c-design Feb 26, 2026
4 checks passed

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a new 'module 2' for handling 'ReproContext' packs, including API endpoints, database storage, and the corresponding data models and persistence logic, structured with a ports and adapters pattern. While the architecture is sound, the API implementation lacks critical security controls, making multiple endpoints vulnerable to Insecure Direct Object Reference (IDOR) due to insufficient user ownership verification for context packs. There is also a risk of prompt injection from unvalidated user input in LLM prompts; implementing a robust authentication and authorization layer is highly recommended. Additionally, suggestions include enhancing error handling for better debug information, utilizing dependency injection for the database store, clarifying data identifier ownership, ensuring accurate progress reporting, and improving logging for data parsing to detect potential data corruption.

Comment on lines +171 to +172
@router.post("/generate")
async def generate_context_pack(request: GenerateContextPackRequest):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

The generate_context_pack endpoint allows a user to specify any user_id in the request body. This user_id is used directly to associate the newly created context pack with a user in the database. Without verifying that the user_id matches the authenticated user, an attacker could create context packs on behalf of other users, potentially leading to data pollution or unauthorized resource consumption.

Comment on lines +189 to +190
async def list_context_packs(
user_id: str = "default",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

The list_context_packs endpoint accepts a user_id as a query parameter and uses it to filter context packs without any authorization check. This is a classic Insecure Direct Object Reference (IDOR) vulnerability, allowing any user to list context packs belonging to any other user by simply providing their user_id.

Comment on lines +211 to +212
@router.get("/{pack_id}")
async def get_context_pack(pack_id: str):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

The get_context_pack endpoint retrieves a context pack by its pack_id from the URL path but fails to verify if the requesting user is the owner of that pack. This allows unauthorized users to access potentially sensitive research data and LLM-generated content in any context pack if they can obtain the pack_id.

Comment on lines +224 to +225
@router.post("/{pack_id}/session")
async def create_repro_session(pack_id: str, request: CreateSessionRequest):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

The create_repro_session endpoint allows creating a reproduction session for any pack_id without verifying ownership. An attacker could use this to trigger session creation for other users' context packs and access the resulting roadmap and prompt data.

Comment on lines +264 to +265
@router.delete("/{pack_id}")
async def delete_context_pack(pack_id: str):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

The delete_context_pack endpoint allows any user to soft-delete any context pack by providing its pack_id. There is no verification that the requesting user owns the pack, leading to an IDOR vulnerability that allows unauthorized data deletion.

"runbook_id": runbook_id,
"initial_steps": initial_steps,
"initial_prompt": (
f"Based on the reproduction context pack for paper {pack.get('paper_id', '')}, "

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-medium medium

The initial_prompt is constructed by embedding the user-supplied paper_id directly into a string. Since paper_id is not validated or sanitized, this is a potential source for prompt injection. If this prompt is subsequently processed by an LLM, a malicious paper_id could manipulate the LLM's behavior.


router = APIRouter()

_store = SqlAlchemyReproContextStore()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using a global instance of SqlAlchemyReproContextStore makes testing more difficult and couples this module to a specific implementation. It's a good practice in FastAPI to use the dependency injection system. This would allow you to easily swap the store implementation for tests or other environments.

For example, you could define a dependency:

def get_store() -> SqlAlchemyReproContextStore:
    return SqlAlchemyReproContextStore()

And then use it in your route functions:

@router.get("/{pack_id}")
async def get_context_pack(pack_id: str, store: SqlAlchemyReproContextStore = Depends(get_store)):
    pack = store.get(pack_id)
    # ...


async def _generate_stream(request: GenerateContextPackRequest):
"""SSE generator for context pack generation via Module 1 ExtractionOrchestrator."""
pack_id = new_context_pack_id()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

There seems to be a redundant generation of pack_id. A pack_id is generated here, but the ExtractionOrchestrator also generates its own pack_id internally. This route then overwrites the orchestrator's ID with its own on line 147. This is confusing and could lead to subtle bugs.

A cleaner approach would be to generate the ID once in this route and pass it to the orchestrator to use. This would likely require a small change to the ExtractionOrchestrator.run method to accept an optional pack_id.

_DONE = object()
_ERROR = object()

total_stages = 2 if request.depth == "fast" else 6

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The total_stages is hardcoded here. However, the actual number of stages depends not only on the depth but also on the paper_type, which is determined inside the ExtractionOrchestrator. This means the progress calculation (stages_done / total_stages) on line 105 can be incorrect.

To fix this, the orchestrator should be the source of truth for the total number of stages. You could modify the on_stage_complete callback to receive the current stage index and the total number of stages from the orchestrator, which has access to the full stage sequence.

Comment on lines +1188 to +1191
try:
return json.loads(self.pack_json or "{}")
except Exception:
return {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Silently catching Exception and returning an empty dictionary can hide data corruption issues. If pack_json contains invalid JSON, it would be valuable to log a warning to make this issue visible for debugging. For example: logging.warning(f"Failed to parse pack_json for pack {self.id}", exc_info=True). The same applies to get_supports on line 1234.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant