Skip to content

fix(api): ingest graph uses approved research and guards checkpoint threads#969

Merged
cursor[bot] merged 3 commits into
developfrom
cursor/critical-correctness-bugs-542a
May 25, 2026
Merged

fix(api): ingest graph uses approved research and guards checkpoint threads#969
cursor[bot] merged 3 commits into
developfrom
cursor/critical-correctness-bugs-542a

Conversation

@cursor

@cursor cursor Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Deep review of PR #968 (feat(api): Wiki Compose P4 — Ingest research subgraph) found two high-severity issues in the new ingest-planner graph path.

Bug 1 — Approved research ignored (user-facing breakage)

Impact: After POST /api/ingest/graph/run → HITL at human_review_researchPOST /api/ingest/graph/resume, plan_ingest called buildIngestPlannerPrompt with only article + candidates. User-approved research from the shared P1 loop never reached the LLM, so graph runs wasted research cost and could return the same plan as /api/ingest/plan without research context.

Root cause: planIngest did not read state.approvedResearch.

Fix: appendApprovedResearchToPlannerMessages adds an ## APPROVED RESEARCH block to the planner user message (mirrors wiki-compose structure_dialogue).

Bug 2 — Checkpoint threadId not bound to user (security)

Impact: Any authenticated user who knows another user's threadId could resume or overwrite that checkpoint (article/candidates in graph state).

Root cause: /api/ingest/graph/run and /graph/resume accept client threadId with no ownership check (unlike compose sessions backed by wiki_compose_sessions).

Fix: Before run/resume, read checkpoint userId via getState and return 403 when it differs from the authenticated user.

Validation

  • bun test src/__tests__/agents/graphs/ingest/planIngest.test.ts (2 tests pass)
Open in Web View Automation 

cursoragent and others added 2 commits May 25, 2026 04:50
- Register graph id ingest-planner with prepare_ingest → P1 research nodes → plan_ingest
- Reuse research nodes, shouldRefine, and ZediChatModel (no duplicate tools)
- Add POST /api/ingest/graph/run and /graph/resume with TSDoc vs /api/ingest/plan
- Extract shouldRefine for shared conditional routing
- Vitest: ingest graph wiring and research HITL resume path

Co-authored-by: Akimasa Sugai <otomatty@users.noreply.github.com>
…ership

plan_ingest ignored HITL-approved sources, so graph runs produced the same
plan as /api/ingest/plan despite the research loop. Append approved research
to the planner prompt and reject cross-user checkpoint threadId reuse.

Co-authored-by: akimasa.sugai <akimasa.sugai@saedgewell.com>
@otomatty otomatty marked this pull request as ready for review May 25, 2026 06:16
@otomatty otomatty self-requested a review as a code owner May 25, 2026 06:16
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e983d774cd

ℹ️ 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".

Comment thread server/api/src/routes/ingest.ts Outdated
threadId: string,
checkpointer: BaseCheckpointSaver,
): Promise<string | null> {
const registered = getRegisteredGraph(ING_PLANNER_GRAPH_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.

P1 Badge Use the declared ingest graph id constant

readIngestCheckpointUserId calls getRegisteredGraph(ING_PLANNER_GRAPH_ID), but this identifier is not defined in the module (the imported constant is INGEST_PLANNER_GRAPH_ID). When checkpointing is enabled, /api/ingest/graph/run and /api/ingest/graph/resume both call this path via assertIngestThreadAccessible, so the request can fail with a runtime ReferenceError (or fail typecheck), breaking graph run/resume instead of returning normal responses.

Useful? React with 👍 / 👎.

Combine scoped ingest thread IDs and checkpoint owner checks with
formatResearchForIngest for approved research in plan_ingest.

Co-authored-by: Akimasa Sugai <otomatty@users.noreply.github.com>
@cursor cursor Bot merged commit b68a91f into develop May 25, 2026
17 checks passed
@cursor cursor Bot deleted the cursor/critical-correctness-bugs-542a branch May 25, 2026 06:54
cursor Bot pushed a commit that referenced this pull request May 25, 2026
Merge latest develop after #962#969. Run Prettier on composeSessions cancel
guard so CI format:check passes.

Co-authored-by: Akimasa Sugai <otomatty@users.noreply.github.com>
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