Skip to content

fix(admin): route chunk quota through count_chunks (DEBT-028)#114

Merged
fvadicamo merged 2 commits into
developfrom
fix/debt-028-chunk-quota-count-chunks
Jul 15, 2026
Merged

fix(admin): route chunk quota through count_chunks (DEBT-028)#114
fvadicamo merged 2 commits into
developfrom
fix/debt-028-chunk-quota-count-chunks

Conversation

@fvadicamo

@fvadicamo fvadicamo commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

What

check_namespace_quota (vektra-admin/quotas.py) counted document_chunks with raw SQL. After ADR-0026 that table is private to the pgvector provider, so in Qdrant mode (every real deployment) it is empty and the chunk quota would never be enforced once the function is wired up.

This routes the chunk count through VectorStoreProvider.count_chunks(), keeping the document branch as-is.

Decision (why route, not remove)

DEBT-028 asked for one of two things depending on whether quota-per-namespace is alive/planned or abandoned. Evidence says alive:

  • REQ-048 (priority must) scopes quota enforcement to Phase 2 — never withdrawn.
  • The admin-enforcement plan is completed and its task 8 built this function deliberately, with "wiring into ingest endpoint deferred to ingest-phase2 plan" — a forward reference, not a drop.
  • Committed scaffolding around it: ORM columns quota_chunks/quota_documents, migration 0002 CHECK constraints, the Namespace shared type fields, ERR-QUOTA-001, and the test suite.
  • Quota is 1 of 4 multi-tenant enforcement layers; the other 3 (RLS, scopes, rate-limit) are wired.

So the function is parked scaffolding for a must requirement, not orphaned dead code. Removing it would delete a committed requirement's foundation (and a deployment could already have quota_* populated). Confirmed no production caller exists (only test_quotas.py), so this is still latent — the fix de-traps it before it is armed.

How

  • Chunk branch calls vector_store.count_chunks(namespace_id) (points for the namespace at its active index version) instead of raw SQL on document_chunks.
  • The provider is injected as a keyword parameter typed as the vektra_shared VectorStoreProvider Protocol. This keeps the vektra-admin module boundary intact (ADR-0005 / import-linter): admin depends only on the shared Protocol, never on vektra-index. The future ingest wiring resolves the provider from the registry, exactly like vektra-index/api.py already does.
  • Document branch unchanged: source_documents is provider-neutral.
  • Raises ValueError if a chunk quota must be enforced but no provider is supplied, so the deferred wiring cannot silently no-op.
  • Also moves the function docstring above the early validation (it sat after a statement, so it was not the function __doc__).

Note for changelog / deployment

Semantics of the chunk count change from "chunks of non-soft-deleted documents in Postgres" to "points in the vector store for the namespace" — the correct measure of what a quota should cap, and the only one available under a non-pgvector provider (ADR-0026).

Tests

  • Chunk and combined quota tests inject a mock provider; added test_missing_vector_store_raises.
  • make lint clean (ruff + mypy + import-linter: 8 contracts kept). make test: 784 passed, 3 skipped.

Traceability

DEBT-028, ADR-0026, ADR-0005, BUG-023, REQ-048, ARCH-047

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Namespace chunk quotas now count chunks from the active vector index, improving quota accuracy across storage providers.
    • Quota checks now clearly require a vector store when new chunks are being added.
    • Document and chunk quota enforcement now follows the correct validation order and returns consistent quota errors.
  • Documentation
    • Updated quota guidance to clarify provider-neutral and provider-specific counting behavior.

…hunks (DEBT-028)

check_namespace_quota counted document_chunks with raw SQL. After ADR-0026 that
table is private to the pgvector provider, so in Qdrant mode (every real
deployment) it is empty and the chunk quota would never be enforced once wired.

Route the chunk count through VectorStoreProvider.count_chunks(), injected as a
parameter typed as the vektra_shared Protocol, which keeps the vektra-admin
module boundary intact (ADR-0005): admin depends only on the shared Protocol,
never on vektra-index. The document branch is unchanged: source_documents is
provider-neutral. Raise ValueError when a chunk quota must be enforced but no
provider is supplied, so the deferred ingest wiring cannot silently no-op.

The function stays dead code (no production caller): it is a deliberately parked
building block for REQ-048 quota enforcement (admin-enforcement plan, completed,
with wiring explicitly deferred to ingest). This de-traps it so the chunk quota
works under any provider when it is finally wired, rather than counting an empty
table.

Also moves the function docstring above the early validation, where it was
placed after a statement and so was not the function __doc__.

Tests: chunk and combined quota tests inject a mock provider; added a test that a
chunk quota without a provider raises ValueError. Full suite: 784 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fvadicamo fvadicamo added bug Something isn't working component:admin vektra-admin component labels Jul 15, 2026
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 35 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: CHILL

Plan: Pro

Run ID: 6d9ba069-c9fd-40f9-8b6a-f9d64420292f

📥 Commits

Reviewing files that changed from the base of the PR and between b5d61eb and 7a59b28.

📒 Files selected for processing (1)
  • CHANGELOG.md
📝 Walkthrough

Walkthrough

check_namespace_quota now keeps document counts in SQL while obtaining chunk counts from an injected VectorStoreProvider. Tests update session and vector-store mocks and cover required injection, skipped counting, ordering, and quota failures.

Changes

Namespace quota enforcement

Layer / File(s) Summary
Provider-backed quota enforcement
vektra-admin/src/vektra_admin/quotas.py
check_namespace_quota accepts a keyword-only vector store, uses provider-backed chunk counts, and raises ValueError when required provider input is missing.
Quota enforcement test coverage
vektra-admin/tests/test_quotas.py
Tests replace session chunk-count results with vector-store mocks and verify invocation behavior, quota ordering, and exceeded-quota responses.

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

Sequence Diagram(s)

sequenceDiagram
  participant check_namespace_quota
  participant AsyncSession
  participant VectorStoreProvider
  check_namespace_quota->>AsyncSession: query namespace and document counts
  check_namespace_quota->>VectorStoreProvider: count_chunks(namespace_id)
  VectorStoreProvider-->>check_namespace_quota: active-index chunk count
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: chunk quota enforcement now uses count_chunks.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/debt-028-chunk-quota-count-chunks

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.

@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 refactors the chunk quota checking logic in vektra-admin to comply with ADR-0026. Instead of querying the document_chunks table directly via raw SQL, chunk counts are now retrieved through the VectorStoreProvider protocol's count_chunks method. The check_namespace_quota function has been updated to accept an optional vector_store provider, raising a ValueError if it is missing when a chunk quota needs to be enforced. Corresponding unit tests have been updated and added to mock this new behavior. There are no review comments, so I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Add an [Unreleased] > Fixed entry alongside the ADR-0026 family (BUG-023,
DEBT-032, DEBT-034), documenting that the latent chunk quota now counts
through VectorStoreProvider.count_chunks() and changes no shipped behavior
today (dead code, no production caller).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Jul 15, 2026
@fvadicamo fvadicamo merged commit 3aff790 into develop Jul 15, 2026
24 checks passed
@fvadicamo fvadicamo deleted the fix/debt-028-chunk-quota-count-chunks branch July 15, 2026 14:08
fvadicamo added a commit that referenced this pull request Jul 15, 2026
…25-quota-enforcement

- Mark DEBT-028 resolved (shipped in #114), with a scope note: it corrected the chunk count to go through count_chunks() but nothing calls check_namespace_quota in the ingest path, so the quota is enforced nowhere
- File FEAT-025 (medium): wire namespace quota enforcement into ingest. REQ-048 (must) names it in its Phase 2 scope; the table columns and the now-correct check exist, but an operator can set a quota and ingest sails past it — a configurable, unenforced control. Same family as DEBT-032
- Fixed in review (gemini): the proposed approach violated the import-linter boundary (vektra_ingest cannot import vektra_admin); rewritten to wire through vektra_shared or the registry, with a green-import-linter acceptance criterion

Reviews: 1/1 addressed (Gemini)
Docs only, no code changes
Refs: DEBT-028, FEAT-025, REQ-048
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working component:admin vektra-admin component documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant