Skip to content

feat: add WithFilter and WithWatchPipeline options to CachedTable - #116

Merged
Prabhjot-Sethi merged 3 commits into
go-core-stack:mainfrom
dev-arya23:feat/cached-table-filter-support
Apr 7, 2026
Merged

feat: add WithFilter and WithWatchPipeline options to CachedTable#116
Prabhjot-Sethi merged 3 commits into
go-core-stack:mainfrom
dev-arya23:feat/cached-table-filter-support

Conversation

@dev-arya23

@dev-arya23 dev-arya23 commented Apr 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

CachedTable.InitializeWithConfig now accepts two new functional options that allow consumers to scope the cache and change stream to a subset of documents in the collection:

  • WithFilter(filter any) — scopes the initial eager load (FindMany) and ReconcilerGetAllKeys to only return entries matching the filter. The filter is passed directly to StoreCollection.FindMany

  • WithWatchPipeline(pipeline any) — scopes the change stream (Watch) to only deliver events matching the pipeline. The pipeline is passed directly to StoreCollection.Watch (expects a mongo.Pipeline)

Both options are fully backward-compatible — existing callers that pass no options continue to get the current behavior (nil filter, nil pipeline = all entries, all events).

Motivation

This is the upstream enabler for agentic-core/core#35 (type-scoped isolation for integration tables). The GenericIntegrationTable in agentic-core/core embeds CachedTable and needs to scope its cache loading and change stream to a specific integration type (e.g., "slack", "github", "email"). Without these options, CachedTable hardcodes nil for both the Watch pipeline and FindMany filter, causing every adapter to load all integrations into its cache and receive all change events — which was the root cause of the cross-adapter data corruption bug fixed in email-adapter#10.

What changed

CachedTableConfig — two new fields:

  • Filter any — optional filter for FindMany (eager load + reconciler)
  • WatchPipeline any — optional pipeline for Watch (change stream)

New option functions:

  • WithFilter(filter any) CachedTableOption
  • WithWatchPipeline(pipeline any) CachedTableOption

CachedTable struct — two new unexported fields:

  • filter any — stored from config, used in eager load and ReconcilerGetAllKeys
  • watchPipeline any — stored from config, passed to Watch

InitializeWithConfig — uses t.watchPipeline instead of nil for Watch, and t.filter instead of nil for FindMany

ReconcilerGetAllKeys — uses t.filter instead of nil for FindMany

How downstream consumers use this

import (
    "go.mongodb.org/mongo-driver/v2/bson"
    "go.mongodb.org/mongo-driver/v2/mongo"
)

// Scoped cache: only loads and watches entries where key.type == \"slack\"
filter := bson.M{\"key.type\": \"slack\"}
pipeline := mongo.Pipeline{
    {{Key: \"$match\", Value: bson.M{\"fullDocument.key.type\": \"slack\"}}},
}

err := table.InitializeWithConfig(col,
    WithFilter(filter),
    WithWatchPipeline(pipeline))

Design decisions

  • New options, not new functions — follows the existing CachedTableOption functional options pattern already established by WithReadThrough(). No new constructor functions needed, no signature changes
  • No changes to Table (non-cached) — the non-cached Table type doesn't have eager loading or a reconciler cache, so these options don't apply to it
  • Filter and pipeline are separate options — they serve different purposes (initial load vs change stream) and may use different query shapes. Keeping them separate gives consumers full control

Test plan

  • go build ./table/... passes
  • go vet ./table/... passes
  • Backward-compatible — existing callers with no options get identical behavior (nil filter, nil pipeline)
  • Existing cached_generic_test.go tests pass unchanged (require MongoDB connection)
  • Integration test with filtered initialization (requires MongoDB connection)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added configuration options to filter cached table data during initial load and key enumeration.
    • Added a watch-pipeline option to limit which change-stream events trigger cache updates.
  • Bug Fixes
    • Validation now runs before initial load and returns clear errors on failure.
    • Improved error handling for eager-load failures (no abrupt process exit).

CachedTable.InitializeWithConfig now accepts two new functional options:

- WithFilter(filter any): scopes the initial eager load (FindMany) and
  ReconcilerGetAllKeys to only return entries matching the filter.
  The filter is passed directly to StoreCollection.FindMany.

- WithWatchPipeline(pipeline any): scopes the change stream (Watch) to
  only deliver events matching the pipeline. The pipeline is passed
  directly to StoreCollection.Watch (expects a mongo.Pipeline).

Both options are fully backward-compatible — existing callers that pass
no options continue to get the current behavior (nil filter, nil pipeline
= all entries, all events).

This enables downstream consumers like GenericIntegrationTable to scope
their cache loading and change stream to a specific subset of documents
(e.g., filtering by integration type), preventing cross-tenant cache
pollution and unnecessary reconciler triggers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 7, 2026

Copy link
Copy Markdown

Walkthrough

Added exported Filter and WatchPipeline to CachedTableConfig with options WithFilter and WithWatchPipeline; CachedTable stores filter and watchPipeline. Initialization now validates filter, uses it for eager key enumeration and ReconcilerGetAllKeys, and passes watchPipeline to the collection watch call; eager-load errors now return wrapped errors.

Changes

Cohort / File(s) Summary
Cache Configuration & Options
table/cached_generic.go
Added Filter any and WatchPipeline any to CachedTableConfig; added option constructors WithFilter and WithWatchPipeline; CachedTable gains internal filter and watchPipeline fields. InitializeWithConfig now validates filter via col.Count, uses filter in FindMany for eager key enumeration and in ReconcilerGetAllKeys, supplies watchPipeline to col.Watch, and converts eager-load failures to returned errors.Internal instead of log.Panicf.

Sequence Diagram(s)

sequenceDiagram
    participant Initializer as Initializer
    participant Collection as Collection (DB)
    participant Cache as CachedTable
    participant Reconciler as Reconciler

    rect rgba(200,200,255,0.5)
    Initializer->>Collection: col.Count(ctx, filter)  -- validate filter
    Collection-->>Initializer: count / error
    end

    rect rgba(200,255,200,0.5)
    Initializer->>Collection: FindMany(ctx, filter)  -- eager key enumeration
    Collection-->>Initializer: keys / error
    Initializer->>Cache: store keys
    end

    rect rgba(255,200,200,0.5)
    Initializer->>Collection: col.Watch(ctx, watchPipeline, handler)  -- register change stream
    Collection-->>Cache: change events
    Cache->>Reconciler: ReconcilerGetAllKeys() uses FindMany(ctx, filter)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nudge the config with a tiny filter paw,
I listen to the pipeline hum and thaw,
Keys gathered neatly from dusk till dawn,
I hop through changes, then quietly yawn,
A rabbit's cheer for code that's spry and raw.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately summarizes the main change: adding two new functional options (WithFilter and WithWatchPipeline) to CachedTable initialization.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@table/cached_generic.go`:
- Around line 208-214: Replace the panic paths that call log.Panicf in
cached_generic.go with error returns and a single upfront filter preflight: when
eager-loading keys (the block using t.readThrough and t.col.FindMany) return the
encountered error to the caller (propagate it out of InitializeWithConfig)
instead of panicking; similarly change the other panic in the
ReconcilerGetAllKeys path to return an error. Add a preflight check of the
caller-supplied filter (WithFilter) during InitializeWithConfig by invoking
t.col.FindMany (or a lightweight validation call) once and returning any error
so read-through mode cannot defer a filter failure to ReconcilerGetAllKeys.
Update InitializeWithConfig and ReconcilerGetAllKeys signatures/returns as
needed to propagate these errors.
- Around line 162-173: After applying opts into CachedTableConfig, validate that
Filter and WatchPipeline are set together: if exactly one of config.Filter or
config.WatchPipeline is non-nil (XOR), reject the partial configuration (return
an error from the construction function or panic consistently with surrounding
API) and surface a clear message referencing WithFilter/WithWatchPipeline
pairing; update the code path that applies opts (the loop over opts and the
assignment to t.readThrough, t.filter, t.watchPipeline) to perform this check
before assigning to t.filter/t.watchPipeline, and update callers/tests
accordingly (or alternatively collapse them into a single scope option if you
prefer that design).
- Around line 96-99: The watch-pipeline example (the pipeline variable and its
use with InitializeWithConfig/WithWatchPipeline) ignores delete events because
delete change streams omit fullDocument; update the example to either (A) match
deletes by including conditions on fullDocumentBeforeChange (MongoDB 6.0+ with
pre-images) and/or documentKey (to capture deletes) or (B) add a clear comment
next to the pipeline and WithWatchPipeline call explaining that simple
fullDocument-based filters drop delete events and that consumers must use
fullDocumentBeforeChange or documentKey/pre-images to handle evictions;
reference the pipeline variable, mongo.Pipeline, InitializeWithConfig, and
WithWatchPipeline when making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: caca7689-6c5f-4342-ba40-36c503a11cfb

📥 Commits

Reviewing files that changed from the base of the PR and between dbf80dd and 97cc253.

📒 Files selected for processing (1)
  • table/cached_generic.go

Comment thread table/cached_generic.go
Comment thread table/cached_generic.go
Comment on lines 162 to +173
// Apply configuration options
config := &CachedTableConfig{
ReadThrough: false, // Default to eager loading
ReadThrough: false, // Default to eager loading
Filter: nil, // Default to all entries
WatchPipeline: nil, // Default to all change events
}
for _, opt := range opts {
opt(config)
}
t.readThrough = config.ReadThrough
t.filter = config.Filter
t.watchPipeline = config.WatchPipeline

@coderabbitai coderabbitai Bot Apr 7, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Keep filter and watch scope in lockstep.

These options now scope eager load/reconciliation and live updates independently. If a caller sets only one, the table drifts out of scope: WithFilter still ingests unrelated watch events, while WithWatchPipeline can leave part of the eagerly loaded cache stale. Please reject partial configuration or replace the pair with a single higher-level scope option.

Possible guard
 	for _, opt := range opts {
 		opt(config)
 	}
+	if (config.Filter == nil) != (config.WatchPipeline == nil) {
+		return errors.Wrapf(errors.InvalidArgument,
+			"WithFilter and WithWatchPipeline must be configured together to keep cache scope consistent")
+	}
 	t.readThrough = config.ReadThrough
 	t.filter = config.Filter
 	t.watchPipeline = config.WatchPipeline

Also applies to: 194-195, 208-211, 267-270

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@table/cached_generic.go` around lines 162 - 173, After applying opts into
CachedTableConfig, validate that Filter and WatchPipeline are set together: if
exactly one of config.Filter or config.WatchPipeline is non-nil (XOR), reject
the partial configuration (return an error from the construction function or
panic consistently with surrounding API) and surface a clear message referencing
WithFilter/WithWatchPipeline pairing; update the code path that applies opts
(the loop over opts and the assignment to t.readThrough, t.filter,
t.watchPipeline) to perform this check before assigning to
t.filter/t.watchPipeline, and update callers/tests accordingly (or alternatively
collapse them into a single scope option if you prefer that design).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Validated this finding — partially valid but I disagree with enforcing the pairing as a hard error.

The PR description explains the design decision: filter and pipeline are intentionally separate options because they serve different purposes (initial load vs change stream) and may use different query shapes. There are legitimate use cases for setting only one:

  • WithFilter alone: Scoped initial load, but accept all change events. The callback handles out-of-scope events gracefully — if a change event arrives for a document outside the filter scope, DBFind fetches it and it gets added to cache (benign for correctness, just slightly over-inclusive). The reconciler will re-enumerate with the filter on its next sweep.
  • WithWatchPipeline alone: Load all entries upfront but only react to specific change events. Useful when the initial load is cheap but you want to reduce change stream noise.

The common downstream use case (type-scoped isolation in GenericIntegrationTable) will always set both — and the InitializeWithConfig example in the docs already shows them used together.

What I'll do: Add a doc comment on InitializeWithConfig noting that for scoped isolation, both options should typically be set together to avoid cache drift. This makes the guidance explicit without rejecting valid partial configurations at runtime.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@dev-arya23, your reasoning is sound. The two axes of filtering genuinely can diverge in query shape (a BSON filter document vs. a change-stream $match pipeline), and the two partial-configuration cases you describe are legitimate:

  • WithFilter only → over-inclusive cache at most; reconciler sweep brings it back in scope on the next pass.
  • WithWatchPipeline only → full eager load with reduced change-stream noise; semantically clean.

Adding a documentation note is the right call. Here's a concrete suggestion for the InitializeWithConfig godoc so it's visible at the call site:

// InitializeWithConfig sets up the Table with the provided db.StoreCollection and configuration options.
// ...
//
// # Scoped isolation
//
// For strict scoped isolation (e.g., multiple CachedTable instances sharing one
// collection), set both WithFilter and WithWatchPipeline together so the eager
// load, reconciler enumeration, and change-stream events all cover the same
// document subset. Setting only one option is valid but may cause the cache to
// be slightly over- or under-inclusive relative to the live change stream until
// the reconciler next sweeps.
//
// Example usage:
// ...

This keeps the API flexible while making the "use both for isolation" guidance discoverable. Looks good to proceed.


📝 Learnings were identified and not saved (knowledge base disabled). Enable

Comment thread table/cached_generic.go

@Prabhjot-Sethi Prabhjot-Sethi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can you check comments provided by coderabbit

- Add delete event warning and fullDocumentBeforeChange example to
  WithWatchPipeline documentation
- Add scope pairing guidance to InitializeWithConfig documentation
- Add filter preflight validation in InitializeWithConfig to catch
  invalid filters at init time with proper error return instead of
  deferring to panic paths
- Convert eager-load FindMany panic to error return since
  InitializeWithConfig already returns error

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dev-arya23

Copy link
Copy Markdown
Collaborator Author

@Prabhjot-Sethi I've reviewed all three CodeRabbit findings and pushed fixes in 668b6e2. Here's a summary:

Finding 1: Watch pipeline drops delete events (line 99) ✅ Fixed

Valid for documentation. The fullDocument-based $match example silently drops MongoDB delete events. The runtime impact is partially mitigated by the reconciler (which periodically evicts stale entries), but the docs should make the trade-off explicit.

Fix: Updated WithWatchPipeline docs with:

  • A WARNING section explaining the delete event limitation
  • A fullDocumentBeforeChange example for immediate delete propagation (MongoDB 6.0+)
  • The original simple example retained with a note that deletes are handled via reconciler

Finding 2: Filter and WatchPipeline should be paired (line 173) ⚠️ Addressed with docs, not hard error

Partially valid but intentionally not enforced at runtime. These options serve different purposes and have legitimate independent use cases (detailed in my reply on the thread). The downstream consumer (GenericIntegrationTable) will always use both.

Fix: Added a NOTE block in InitializeWithConfig docs explaining that for scoped isolation, both options should typically be set together to avoid cache drift.

Finding 3: Panic on filter errors (line 214) ✅ Fixed

Pre-existing pattern, but valid that WithFilter increases the surface area. The log.Panicf calls existed before this PR — we just changed nil to t.filter.

Fix: Two improvements:

  1. Filter preflight validation — if a filter is configured, we run a lightweight FindMany with SetLimit(0) during init to catch invalid filters early with a proper error return
  2. Converted eager-load panic to error return — the InitializeWithConfig panic on eager-load FindMany failure is now return errors.Wrapf(errors.Internal, ...) since the function already returns error

Note: The ReconcilerGetAllKeys panic is left as-is since changing its return signature would be a reconciler interface change (good follow-up, separate PR).

@coderabbitai coderabbitai 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.

♻️ Duplicate comments (1)
table/cached_generic.go (1)

219-227: ⚠️ Potential issue | 🟠 Major

Replace FindMany(SetLimit(0)) with Count() for lightweight filter validation.

The FindMany call with SetLimit(0) retrieves and decodes all matching documents from the collection, contradicting the code's claim of "lightweight" validation. On large collections, this will materially impact initialization time and memory usage. Use Count() instead, which validates the filter without fetching document data.

Suggested fix
-		var preflight []keyOnly[K]
-		preflightOpts := options.Find().SetLimit(0)
-		if err := col.FindMany(context.Background(), t.filter, &preflight, preflightOpts); err != nil {
+		if _, err := col.Count(context.Background(), t.filter); err != nil {
 			return errors.Wrapf(errors.InvalidArgument, "WithFilter: filter validation failed: %s", err)
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@table/cached_generic.go` around lines 219 - 227, The preflight filter
validation currently uses col.FindMany with options.Find().SetLimit(0) (see
t.filter, preflight, preflightOpts, col.FindMany) which still decodes matching
documents; replace this with a lightweight count operation (e.g., col.Count or
CountDocuments) that takes the same context and t.filter, check only the error
returned, and wrap it with the existing errors.Wrapf message ("WithFilter:
filter validation failed: %s"); remove preflight/preflightOpts usage since no
result slice is needed. Ensure the new call uses context.Background() and
preserves the same error handling path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@table/cached_generic.go`:
- Around line 219-227: The preflight filter validation currently uses
col.FindMany with options.Find().SetLimit(0) (see t.filter, preflight,
preflightOpts, col.FindMany) which still decodes matching documents; replace
this with a lightweight count operation (e.g., col.Count or CountDocuments) that
takes the same context and t.filter, check only the error returned, and wrap it
with the existing errors.Wrapf message ("WithFilter: filter validation failed:
%s"); remove preflight/preflightOpts usage since no result slice is needed.
Ensure the new call uses context.Background() and preserves the same error
handling path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f7ba8fbf-07d2-465a-9440-657ca07d07b3

📥 Commits

Reviewing files that changed from the base of the PR and between 97cc253 and 668b6e2.

📒 Files selected for processing (1)
  • table/cached_generic.go

@dev-arya23

Copy link
Copy Markdown
Collaborator Author

Addressing CodeRabbit re-review finding: FindMany(SetLimit(0))Count()

Good catch from the re-review. The StoreCollection interface does expose Count(ctx, filter) (int64, error), which validates the filter server-side without fetching or decoding any documents.

The current preflight uses FindMany with SetLimit(0), but SetLimit(0) in MongoDB actually means "no limit" — so on large collections this would decode all matching documents just to validate the filter shape. Count() is the correct lightweight validation call here.

I'll push a fix shortly:

-	var preflight []keyOnly[K]
-	preflightOpts := options.Find().SetLimit(0)
-	if err := col.FindMany(context.Background(), t.filter, &preflight, preflightOpts); err != nil {
+	if _, err := col.Count(context.Background(), t.filter); err != nil {
 		return errors.Wrapf(errors.InvalidArgument, "WithFilter: filter validation failed: %s", err)
 	}

This also removes the unused options import if it was only used for Find().SetLimit(0).

…t validation

Count() validates the filter server-side without fetching or decoding
any documents, making it a truly lightweight preflight check.

SetLimit(0) in MongoDB means "no limit", so the previous FindMany call
would actually decode all matching documents — defeating the purpose of
a lightweight validation.
@dev-arya23

Copy link
Copy Markdown
Collaborator Author

Pushed fix in cdf917e — replaced FindMany(SetLimit(0)) with col.Count() for the filter preflight validation.

All CodeRabbit findings addressed:

# Finding Status Commit
1 Watch pipeline drops delete events ✅ Fixed (docs + warning) 668b6e2
2 Filter + WatchPipeline pairing ✅ Addressed (doc guidance, not hard error) 668b6e2
3 Panic on filter errors → error return ✅ Fixed (preflight + error return) 668b6e2
4 FindMany(SetLimit(0))Count() ✅ Fixed cdf917e

@Prabhjot-Sethi — all CodeRabbit findings have been addressed across 3 commits. Ready for your review when you get a chance.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
table/cached_generic.go (1)

219-228: Good preflight validation — consider preserving error chain.

The Count-based preflight is the right approach for lightweight server-side validation. However, the error at line 226 embeds err as a string via %s, which loses the original error for chain inspection (e.g., errors.Is/errors.As).

If error chain preservation is needed elsewhere in the codebase, consider wrapping the error properly:

♻️ Optional: preserve error chain
 	if t.filter != nil {
 		if _, err := col.Count(context.Background(), t.filter); err != nil {
-			return errors.Wrapf(errors.InvalidArgument, "WithFilter: filter validation failed: %s", err)
+			return errors.Wrapf(err, "WithFilter: filter validation failed")
 		}
 	}

Note: This depends on how your custom errors.Wrapf handles wrapping — if the first argument is the sentinel error code, the current pattern may be intentional.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@table/cached_generic.go` around lines 219 - 228, The preflight Count error
currently embeds err as a string which breaks the error chain; update the
WithFilter preflight so the returned error wraps the original err (preserving
chain) instead of using %s — e.g., change the errors.Wrapf call around
col.Count(context.Background(), t.filter) to use an error-wrapping directive
(such as %w) or the equivalent overload of errors.Wrapf/Wrap that accepts the
cause so callers can use errors.Is/errors.As to inspect the original error; keep
the same message context ("WithFilter: filter validation failed") and reference
t.filter, col.Count and errors.Wrapf when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@table/cached_generic.go`:
- Around line 219-228: The preflight Count error currently embeds err as a
string which breaks the error chain; update the WithFilter preflight so the
returned error wraps the original err (preserving chain) instead of using %s —
e.g., change the errors.Wrapf call around col.Count(context.Background(),
t.filter) to use an error-wrapping directive (such as %w) or the equivalent
overload of errors.Wrapf/Wrap that accepts the cause so callers can use
errors.Is/errors.As to inspect the original error; keep the same message context
("WithFilter: filter validation failed") and reference t.filter, col.Count and
errors.Wrapf when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8fe21986-6256-4804-82c0-7721b193b2d3

📥 Commits

Reviewing files that changed from the base of the PR and between 668b6e2 and cdf917e.

📒 Files selected for processing (1)
  • table/cached_generic.go

@Prabhjot-Sethi
Prabhjot-Sethi merged commit 4cb9bc7 into go-core-stack:main Apr 7, 2026
1 check passed
@dev-arya23 dev-arya23 mentioned this pull request Apr 7, 2026
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.

2 participants