Skip to content

feat(graph-rag): report gleaning as its own extraction stage - #145

Merged
kl3inIT merged 1 commit into
mainfrom
feat/assistant-generation-telemetry
Jul 30, 2026
Merged

feat(graph-rag): report gleaning as its own extraction stage#145
kl3inIT merged 1 commit into
mainfrom
feat/assistant-generation-telemetry

Conversation

@kl3inIT

@kl3inIT kl3inIT commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Continues the Phase 2 stage gap. Stage declared fourteen values and production emitted ten; this makes it eleven.

What was invisible

Gleaning is the second extraction round — a per-chunk model call that recovers entities the first round missed. It is also the part of extraction that a profile can disable and a token guard can decline at runtime. Folded into EXTRACT, all three cases looked identical: gleaning working, gleaning configured off, and gleaning being declined chunk after chunk because the prompt grew too large.

The extractor was already recording which. ExtractionDiagnostics carries a per-round metric and a GleaningOutcome, and every ExtractedChunk carries it into the worker. Nothing published it — the same pattern as the token usage in #142.

Shape

Emitted once per indexing job, when the profile enables gleaning:

  • inputCount — chunks eligible
  • outputCount — chunks that completed a gleaning round

A declined round is the gap between them, which is what makes the token guard visible.

Duration is the second round's model time alone, aggregated across chunks that glean concurrently. That is what gleaning cost, not how long it took, and it is nested inside EXTRACT's wall clock rather than sequential with it — so stage durations within one job are not additive. Said explicitly in the code and the spec, because a dashboard that sums them would be wrong and nothing else would tell it so.

Nothing is emitted when the profile disables gleaning. A zero-valued series would claim a round that was never configured to run.

GENERATE and TTFT are not here

They were the next items on the plan and I stopped short of implementing them, because they are not a wiring task:

  • QueryOutputMode.ANSWER exists, but GraphRagRetrievalPolicy pins CONTEXT — generation was deliberately moved into the application shell so the shell can re-verify the evidence closure before delivery.
  • AssistantService sits above PermissionAwareKnowledgeSearch, which has a second, non-GraphRAG implementation (CanonicalHybridKnowledgeSearch) selected by configuration.
  • GraphRagEvent requires a non-null operationId that only the GraphRAG service mints and that never leaves it.

So emitting Stage.GENERATE from the assistant either labels canonical-engine turns as GraphRAG stages, or threads a GraphRAG identifier through an engine-neutral interface. CLAUDE.md requires an independent architecture challenge before that class of decision.

challenge-generation-telemetry.md states the proposal, the repository evidence, and the strongest counterargument against my own proposal — that GraphRagEventSink is the enforcement point of the payload boundary, and generation is the one stage where prompts and completions actually exist, so a second telemetry surface for exactly that stage is how a structural guarantee decays into a conventional one.

Also found, not fixed

ExtractionRoundMetrics already carries providerInputTokens and providerOutputTokens per round, unpublished. Ingestion spend is invisible while retrieval spend is not. The TokenUsage record from #142 does not fit — its channels are retrieval's — so it needs its own shape rather than a forced reuse. Recorded on the plan.

Verification

:apps:worker:test, :components:graph-rag-core:test. Green.

🤖 Generated with Claude Code

Gleaning is the second extraction round: a per-chunk model call that recovers
entities the first round missed, and the part of extraction a profile can
disable or a token guard can decline. Folded into EXTRACT it was
indistinguishable from the round that always runs, so a deployment could not
tell gleaning working from gleaning silently not happening.

The extractor was already recording exactly that. ExtractionDiagnostics carries
a per-round metric and a gleaning outcome, every ExtractedChunk carries it into
the worker, and nothing published it.

The stage counts eligible chunks against chunks that completed a round, so a
declined round shows as the gap between the two. Its duration is the second
round's model time alone, aggregated across chunks that glean concurrently — it
is what gleaning cost rather than how long it took, and it is nested inside
EXTRACT's wall clock, so stage durations within one job are not additive.

A profile with gleaning disabled emits nothing. A zero-valued series would claim
a round that was never configured to run, which is the same lie as an empty
series that looks like silence.

GENERATE and time to first token are not here. Generation happens in the
application shell rather than the GraphRAG runtime, above an engine-neutral
retrieval interface with a non-GraphRAG implementation, so wiring it to a
GraphRAG stage is a boundary decision rather than a wiring one. Recorded with
its strongest counterargument in challenge-generation-telemetry.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@kl3inIT, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 46 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fa7023d9-fa74-4121-b2ef-67bc9337c5a9

📥 Commits

Reviewing files that changed from the base of the PR and between 22234c9 and 551be1e.

⛔ Files ignored due to path filters (4)
  • docs/increments/active/2026-07-29-observability-pipeline/challenge-generation-telemetry.md is excluded by !docs/**
  • docs/increments/active/2026-07-29-observability-pipeline/plan.md is excluded by !docs/**
  • docs/specs/domains/secure-graph-rag.md is excluded by !docs/**
  • docs/tests/domains/secure-graph-rag.md is excluded by !docs/**
📒 Files selected for processing (2)
  • apps/worker/src/main/java/com/orgmemory/worker/graph/GraphIndexingProcessor.java
  • apps/worker/src/test/java/com/orgmemory/worker/graph/GraphIndexingProcessorTests.java

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.

@kl3inIT

kl3inIT commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@kl3inIT
kl3inIT merged commit fcb88fb into main Jul 30, 2026
14 checks passed
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