fix(interop)!: reject double-dot interop segments (LAB-5906) - #391
Conversation
The interop segment pattern admits `..` inside a segment (`a..b`), but the CachekitIO server rejects `..` anywhere in a key (protocol spec/cache-key-format.md#server-side-requirements, Traversal row), so such a key failed with 400 on every request while working on Redis and file backends. validate_segment now raises InteropError for a namespace or operation containing `..`, after the grammar check; decoration surfaces it as ConfigurationError, on every backend. A lone `.` stays valid. The interop guide states the rule. Re-vendors test-vectors/interop-mode.json 1.2.0 byte-for-byte from cachekit-io/protocol#94 (sha256 702613766d1b92bc3a337627a96b9aedc89abfeb4d9208c2bb00c9539a0a1f40; 35 key / 13 error vectors) and updates the sha and count pins. BREAKING CHANGE: an interop namespace or operation containing `..` now raises ConfigurationError at decoration time, on every backend. Rename the segment; its keys become a full cache miss.
|
Warning Review limit reachedNext included review available in 40 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: cachekit-io/cachekit-py/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (7)
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. Comment |
Code Review Completed! 🔥The code review was successfully completed based on your current configurations. Kody Guide: Usage and ConfigurationInteracting with Kody
Providing Context (Files & MCPs)Add these hints in your PR description (or a comment) to unlock deeper checks:
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Summary
Interop mode now rejects any
namespaceoroperationsegment containing... The segment grammar^[a-z0-9][a-z0-9._-]{0,63}$permits.., but the CachekitIO server rejects..anywhere in a key. Previously the SDK accepted such segments and produced keys that returned400on every CachekitIO request while working on other backends. The rule now applies on every backend, so a segment that is valid on one backend is valid on all.Modified Public APIs
cachekit.interop.validate_segment(name, segment): raisesInteropErrorwhen the value contains...invalid interop {name} {value!r}: must not contain '..', because the CachekitIO server rejects '..' anywhere in a key.ns,nsapi) check.generate_interop_key(...)andvalidate_interop_config(...): inherit the rejection throughvalidate_segment...segment surfaces asConfigurationErrorat decoration time, before any call is made..remain valid, including a trailing dot (get.), a dotted namespace (app.v1) and multi-dot names (a.b.c,users.fetch.by_id).An inline comment explains why a per-segment check covers the whole key: the
:delimiters separate the segments and the args hash is hex, so any..in a key must lie inside one segment.Conformance Fixture
interop-mode.json1.2.0 from fix(interop)!: forbid double-dot inside interop segments (LAB-5906) protocol#94.702613766d1b92bc3a337627a96b9aedc89abfeb4d9208c2bb00c9539a0a1f40..secrets.baselineupdates only line numbers for existing fixture hex strings and thegenerated_attimestamp.Documentation
docs/features/interop-mode.mdstates the..rule, and that both segment rules apply on every backend, in two places:ConfigurationErrorat decoration timeTests
test_interop_model.py: newTestDoubleDotSegmentsclass.a..b,x..y,users.v1..beta,a...bandx...test_interop_decorator.py:ConfigurationErrorfor a..namespace and for a..operation.lone_dots_stay_validvector decorates and writes exactly the pinned key.test_interop_vectors.py: updated SHA and count pins.Breaking Change
An interop namespace or operation containing
..now fails at decoration time withConfigurationErroron all backends. Affected segments must be renamed, and their keys become a full cache miss.Summary
The interop/v1 segment pattern admits
..inside a segment (a..b), but the CachekitIO server rejects..anywhere in a key (cache-key-format.md → Server-Side Requirements, the Traversal row). So this SDK accepted such a segment and minted a key that fails with400on every CachekitIO request, while the same key works on other backends. cachekit-io/protocol#94 forbids..in either segment; this PR implements it.Changes
validate_segment(src/cachekit/interop.py) raisesInteropErrorfor a namespace or operation containing.., after the grammar check. Decoration surfaces it asConfigurationError, on every backend. A lone.stays valid, including at the end of a segment.interop-mode.json1.2.0 byte-for-byte from cachekit-io/protocol#94 (sha256702613766d1b92bc3a337627a96b9aedc89abfeb4d9208c2bb00c9539a0a1f40; 35 key / 13 error vectors) and updates the sha and count pins. The new vectors arereject_double_dot_namespace(a..b),reject_double_dot_operation(x..) andlone_dots_stay_valid(app./users.fetch.by_id).docs/features/interop-mode.mdstates the rule in the cross-SDK contract and the guardrails table.tests/unit/protocol/test_interop_model.py(keygen and config rejecta..b,x..y,users.v1..beta,a...b,x..; acceptapp.v1,get.,a.b.c),test_interop_decorator.py(decoration raisesConfigurationErrorfor a..namespace and operation;lone_dots_stay_validdecorates and writes the pinned key), and the vector suite's sha and count pins (test_interop_vectors.py)..secrets.baseline: timestamp only.Merge order
Merge cachekit-io/protocol#94 first. The vendored fixture must stay byte-identical to
test-vectors/interop-mode.jsonat its merge commit (sha256 above).Breaking
An interop namespace or operation containing
..now raisesConfigurationErrorat decoration time, on every backend. Rename the segment; its keys become a full cache miss. Before this change, such a key already failed on CachekitIO.Release notes read the breaking note from this block:
BEGIN_COMMIT_OVERRIDE
fix(interop)!: reject double-dot interop segments (LAB-5906) (#391)
BREAKING CHANGE: an interop namespace or operation containing
..now raisesConfigurationErrorat decoration time, on every backend; the manualgenerate_interop_keyhelper raisesInteropError. Rename the segment; its keys become a full cache miss.END_COMMIT_OVERRIDE
Test plan
uv run ruff check src/ tests/anduv run ruff format --check src/ tests/uv run pytest tests/unit/ tests/critical/ -m "not slow": 3445 passed, 23 skippeduv run pytest docs/features/interop-mode.md src/cachekit/interop.py(markdown and doctests): passed..tests and bothreject_double_dot_*vectors fail