Skip to content

fix(exec): cut a map reply at the row limit and mark it - #222

Merged
zsltg merged 3 commits into
mainfrom
fix/exec-cut-signal
Oct 31, 2026
Merged

zsltg merged 3 commits into
mainfrom
fix/exec-cut-signal

Conversation

@zsltg

@zsltg zsltg commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner

Summary

CouchDB and HBase return a map from a native query: a Mango find gives {"docs": [...], "bookmark": ...}, and an HBase scan gives {rowkey: row}. The iq_exec cap marks only a list reply as truncated, so #215 left these two drivers out: a cut map would have looked complete. They still read the whole native reply into memory, and the cap only limited what the agent saw.

Change

  • A cut notice in the context, next to the row limit: query.WithRowCutNotice, query.NoteRowCut, and the helper query.CutAtLimit(ctx, n), which a non-list driver calls after it reads row n.
  • The WithRowLimit doc now states both contracts. A list driver returns up to n rows; the caller asks for one more than it shows. A driver whose reply is not a list reads at most n rows; if the n-th row exists, it drops that row, keeps n-1, and reports the cut.
  • CouchDB applies this to the docs of a find. A cut reply has no bookmark, because the driver did not read the reply to its end. The deferred close still releases the result set.
  • HBase applies it to the rows of scan <table> and closes the scanner. get returns one row and is unchanged.
  • iq_exec installs the sink and sets truncated for any reply shape when a cut was reported. The byte cap and the list cap do not change.
  • Without a limit, both drivers read every row as before.
  • Docs: docs/docs/agents.md now lists CouchDB and HBase, and says that their map reply comes back with truncated set when rows were cut.

Checks

  • make check
  • make docs
  • scripts/mutation-gate.sh: left to CI. Locally, the CouchDB test container refused its login ("Account is temporarily locked"), so the baseline run could not start.
  • make cover: left to CI
  • make security: left to CI
  • End-to-end tests: left to CI
  • Tests added: TestRowCutNotice, TestNoteRowCutWithoutSinkDoesNothing, TestNoteRowCutCallsTheSink, TestQueryRowLimit (CouchDB: limit 3 over 5 docs gives 2 docs, no bookmark, the cut, and 3 reads), TestQueryScanRowLimit (HBase: the same, and the scanner closes once), TestMCPExecMarksACutMapReply. They fail without the change.
  • scripts/capabilities.sh: not needed, go.mod and go.sum did not change
  • Docs updated in the same change

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Map query results from CouchDB and HBase now report truncated: true when a row limit cuts the results. Rows that fit are retained, and the result data remains unchanged otherwise.
    • Truncation is reported when either the row limit or result caps cut the response.
  • Documentation
    • Clarified that the CLI iq exec remains uncapped and returns the full reply.

CouchDB and HBase return a map from a native query: a Mango find gives
{"docs": [...]}, and an HBase scan gives {rowkey: row}. The iq_exec cap
marks only a list reply as truncated, so these two drivers read their
whole reply into memory, and a cut would have looked complete.

Add a cut notice in the context: WithRowCutNotice, NoteRowCut, and the
helper CutAtLimit. A driver whose reply is not a list reads at most the
limit of rows. If the last of them exists, it drops that row, keeps one
row less, and reports the cut. iq_exec then sets truncated for any reply
shape. The WithRowLimit doc states both contracts.

CouchDB applies this to the docs of a find, and a cut reply has no
bookmark. HBase applies it to the rows of a scan and closes the
scanner. Without a limit, both read every row as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Zsolt Gaspar <17578237+zsltg@users.noreply.github.com>
@zsltg

zsltg commented Oct 30, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 7422c3d and 78429fe.

Files selected for processing: 9
  • cmd/mcp_exec_test.go
  • cmd/mcp_tools.go
  • docs/docs/agents.md
  • drivers/couchdb/couchdb.go
  • drivers/couchdb/mock_test.go
  • drivers/hbase/hbase.go
  • drivers/hbase/store_test.go
  • internal/query/query.go
  • internal/query/query_test.go

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

CouchDB and HBase now report when row-limited reads are cut short. The MCP iq_exec handler combines that signal with result-cap truncation when it marks replies. The changes also add query-context support, tests for row-limit behavior, and documentation updates.

Changes: Row-limit cut reporting

Layer / File(s) Summary
Query row-cut notice contract
internal/query/query.go, internal/query/query_test.go
The query package adds a context callback and CutAtLimit. Its documentation distinguishes list replies, non-list replies, and single-document replies. Tests cover cut thresholds and callback behavior.
CouchDB and HBase row-limit handling
drivers/couchdb/couchdb.go, drivers/couchdb/mock_test.go, drivers/hbase/hbase.go, drivers/hbase/store_test.go, docs/docs/agents.md
CouchDB and HBase stop before decoding the limit-th row and report the cut. Tests check row counts and cut behavior. The documentation describes the drivers’ row caps and the uncapped CLI iq exec.
MCP truncation reporting
cmd/mcp_tools.go, cmd/mcp_exec_test.go
toolExec marks results truncated when result capping or a driver row-cut notice reports truncation. Tests check that map replies remain unchanged and that their truncated status matches the driver notice.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant toolExec
  participant CouchDBStoreQuery
  participant HBaseExecScan
  participant queryCutAtLimit as query.CutAtLimit
  participant rowCutCallback
  toolExec->>toolExec: Register row-cut callback
  alt CouchDB query
    toolExec->>CouchDBStoreQuery: Query with row limit
    CouchDBStoreQuery->>queryCutAtLimit: Check row count
  else HBase scan
    toolExec->>HBaseExecScan: Scan with row limit
    HBaseExecScan->>queryCutAtLimit: Check row count
  end
  queryCutAtLimit->>rowCutCallback: Report row cut at limit
  rowCutCallback-->>toolExec: Set atomic cut flag
  toolExec->>toolExec: Combine cut flag with result-cap truncation
Loading

Possibly related PRs

  • zsltg/iq#207: Adds iq_exec item and byte caps and introduces query.WithRowLimit.
  • zsltg/iq#215: Adds native-driver stopping behavior at the query.WithRowLimit cap.
Merge Risk: Minimal · up to 78429

No merge-blocking issue was identified.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly identifies the main change: cutting map replies at the row limit and marking them as truncated.
Description check Passed The description explains the problem, implementation, affected drivers, behavior, tests, documentation, and checks completed or deferred to CI. It provides sufficient detail despite using Summary and …
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains the problem, implementation, affected drivers, behavior, tests, documentation, and checks completed or deferred to CI. It provides sufficient detail despite using Summary and Change headings instead of the template's What and why heading.

Full details: Docstring Coverage

Explanation

Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 7 functions across 8 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@coderabbitai

coderabbitai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

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.

codescene-access[bot]

This comment was marked as outdated.

CodeScene found execScan at its complexity limit after the cut check.
addScanRow now adds one result and reports whether the scan is done.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Zsolt Gaspar <17578237+zsltg@users.noreply.github.com>
codescene-access[bot]

This comment was marked as outdated.

@codecov

codecov Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.92%. Comparing base (7422c3d) to head (78429fe).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #222   +/-   ##
=======================================
  Coverage   96.91%   96.92%           
=======================================
  Files         154      154           
  Lines       15187    15214   +27     
=======================================
+ Hits        14719    14746   +27     
  Misses        467      467           
  Partials        1        1           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

kivik gives the metadata of a result set only once its rows are read to
the end, so a find that the row limit cut gets no bookmark anyway. The
cut flag and its early return changed nothing, and the mutation gate
found both as escaped. Remove them and say why in a comment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Zsolt Gaspar <17578237+zsltg@users.noreply.github.com>
@zsltg

zsltg commented Oct 30, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

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.

@zsltg

zsltg commented Oct 31, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Oct 31, 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.

@zsltg
zsltg merged commit b88d92a into main Oct 31, 2026
45 checks passed
@zsltg
zsltg deleted the fix/exec-cut-signal branch October 31, 2026 08:58
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