Trying to distill to 1st principles here - we have a few things to optimize for 
or make decisions on. Each of the following 3 have identical affordances 
between a separate cassandra-utils vs. lib published from C*:
 1. Who can depend on the code. This is priority target #1; both fix.
 2. Who breaks when the code changes. Right now it's everyone but C*. Either 
basic semver or per-API versioning fix this.
 3. When integration happens. C* is pre-merge, everyone else is at time of 
integration.
The knobs we can tune as I see it are:
 1. Do we decouple API changes and bugfix availability? I say yes. This 
requires either one branch w/per-API versioning (as proposed in CEP), or semver 
utils where we only do breaking API changes on MAJOR.
 2. When does that integration break surface? Status quo == lazy at integration 
time. Alternative would be CI targets wherever utils lives to surface breaks 
immediately. 
Some more observations / axioms:
 • Any combination of approaches (cassandra-utils vs. lib, versioned APIs vs. 
non) will be a strict improvement on copy-pasted duplicated code.
 • Any approach w/out API versioning couples bugfix adoption w/API integration.
 • Any versioned API approach pushes that friction upstream to people working 
on the shared utils to keep that separate, whether due to annotation-based 
versioning or maintaining multiple branches.

I think it's reasonable for us to target removing duplicated code and 
decoupling bug-fix integration in this shared code from API surface area change 
adoption. Before going further, do we broadly agree on these 2 goals?


On Wed, Aug 19, 2026, at 4:29 AM, Štefan Miklošovič wrote:
> I am not against the annotation as such but I think that we are trying
> to do a lot of things at once. Just move the code over to utils, make
> it 0.1.x, wait until it stabilizes, see what has a tendency to break /
> change a lot and _then_ annotate if we still find it necessary to do
> so. If you asked me "what to annotate with what" right now I would not
> be able to say.
> 
> I just prefer to move things progressively and not put annotations
> into something we will be obliged to live with from day one without
> gathering some evidence first if it is even really necessary and what
> would that look like in practice etc ... Maybe we realize that, in
> utils, just living with Semver and not having annotations at all is
> actually good enough, but I just do not know right now.
> 
> On Wed, Aug 19, 2026 at 2:30 AM Yifan Cai <[email protected]> wrote:
> >
> > Sharing my 2 cents.
> >
> > If we want the utils library to provide stable APIs from the start, 
> > deferring the annotation decision isn't deferring anything — it's deciding 
> > for public-by-default.
> >
> > If we want to preserve the flexibility of making breaking changes (since 
> > the version is 0.x), I'm good with deferring and getting things moving.
> >
> > Honestly, from the ecosystem projects' perspective — not just Cassandra, 
> > but also the projects under the same Cassandra umbrella — having the API 
> > lifecycle annotated makes life easier for both consumers and maintainers. 
> > That said, I am not going to die on this hill.
> >
> > - Yifan
> >
> > On Tue, Aug 18, 2026 at 2:45 PM Štefan Miklošovič <[email protected]> 
> > wrote:
> >>
> >> I feel like we are trying to solve everything at once. I think that
> >> extracting the utility code outside of Cassandra is already enough to
> >> deal with for now. That extraction might be a bit tricky, especially
> >> if it depends on some 3rd party library etc ... If it is really only
> >> about the candidates put into examples in the Scope section of the
> >> CEP, the dependencies should be minimal. We should strive for utils
> >> depending on the minimum of dependencies because as soon as it is
> >> going to be used in another project which is itself depending on other
> >> stuff there might be conflicts etc ... If utils is "pure Java" or
> >> close enough to that then this problem is minimized.
> >>
> >> I would leave the discussion about annotation public / private etc.
> >> for another time / outside of this CEP. In utils, for starters I would
> >> just follow Semver (non-event for patch releases, code change on the
> >> consumer side for minor releases) and leave annotations in Cassandra
> >> out of this.
> >>
> >> On Tue, Aug 18, 2026 at 11:00 PM David Capwell <[email protected]> wrote:
> >> >
> >> > Thanks for the reply Francisco!
> >> >
> >> > > Instead, I was thinking that producing an artifact with utils
> >> > > as part of the Cassandra release process is probably a
> >> > > more sustainable approach.
> >> >
> >> > The main utility that has caused this debate are the test utilities 
> >> > which we do not publish as part of the cassandra release. Cassandra also 
> >> > only releases every 1-2 years so being able to pick up changes to these 
> >> > test utilize (including bug fixes) would have to follow that same 
> >> > timeline, making it harder to depend on; this was the motivating reason 
> >> > for extracting outside of Cassandra.
> >> >
> >> >
> >> > > On Aug 18, 2026, at 1:17 PM, Francisco Guerrero <[email protected]> 
> >> > > wrote:
> >> > >
> >> > > I'm not convinced having utils in an external repo will
> >> > > be a good idea. We already have problems with
> >> > > Analytics/Sidecar repositories and you've been helping
> >> > > with the effort of consolidating those repos.
> >> > >
> >> > > Instead, I was thinking that producing an artifact with utils
> >> > > as part of the Cassandra release process is probably a
> >> > > more sustainable approach. I would expect the classes in
> >> > > this artifact will be mostly stable and don't expect many
> >> > > changes. Ecosystem projects can consume the released
> >> > > utils artifact.
> >> > >
> >> > > On 2026/08/18 14:05:05 Josh McKenzie wrote:
> >> > >>> We just make sure the builds don't break.
> >> > >> To ensure builds don't break across all projects using utils,  we'd 
> >> > >> need to integrate a basic build of all GA supported branches of 
> >> > >> Cassandra and all ecosystem projects as a CI gate for the 
> >> > >> cassandra-utils project. That would foist needing to fix all 
> >> > >> dependents up to the workflow of committing an API breaking change, 
> >> > >> onto the person making the change to utils or onto the delegates they 
> >> > >> find at that time. This is predicated on the "one branch to rule them 
> >> > >> all" model though.
> >> > >>
> >> > >> The alternative (existing API endpoints are static but you can add 
> >> > >> new ones) decouples that need to update all dependents to whenever 
> >> > >> they want to integrate that new API and takes that burden off the 
> >> > >> person making the change to utils. In theory we'd get to have our 
> >> > >> cake and eat it too (i.e. frictionless iteration on an API endpoint 
> >> > >> flagged @BETA, users have stable APIs they can rely on with @STABLE), 
> >> > >> at the risk / cost of having a proliferation of @DEPRECATED APIs 
> >> > >> littered behind us.
> >> > >>
> >> > >> My intuition is that the latter is actually significantly less work 
> >> > >> for anyone that wants to modify utils vs. the former and the risk of 
> >> > >> that long tail of deprecated API proliferation isn't that high.
> >> > >>
> >> > >>> I’m against creating any API boundaries we need to maintain for any 
> >> > >>> external users
> >> > >> 100% agree. I think we get this as a free side-effect of a model 
> >> > >> where we have STABLE flagged APIs and BETA, since it defers that 
> >> > >> integration cost to *any* consumer's timeline. i.e. someone could 
> >> > >> iterate on an API they need a change for in cassandra-analytics and 
> >> > >> core cassandra can keep trucking with a now @DEPRECATED endpoint 
> >> > >> until such time as it wants to integrate the new structure.
> >> > >>
> >> > >> One other point that's come up in conversation offline is around 
> >> > >> bug-fixing; being able to fix bugs in implementation w/out consumers 
> >> > >> having to also refactor to new API endpoints is just good hygiene for 
> >> > >> limiting blast radius of changes.
> >> > >>
> >> > >>
> >> > >> On Tue, Aug 18, 2026, at 4:25 AM, Benedict Elliott Smith wrote:
> >> > >>> I’m hard -1 on this the
> >> > >>>
> >> > >>> I’m very pro code sharing between Cassandra projects, but these do 
> >> > >>> not need any special handling - we just make sure the builds don’t 
> >> > >>> break. I’m against creating any API boundaries we need to maintain 
> >> > >>> for any external users
> >> > >>>
> >> > >>> On 2026/08/17 20:33:32 David Capwell wrote:
> >> > >>>>> They're all internal, this is a convenience to improve code 
> >> > >>>>> sharing.
> >> > >>>>
> >> > >>>> Once they go into utils they are not “internal” (whatever that 
> >> > >>>> means).  Why I started this effort in the first place is that the 
> >> > >>>> test utilities have been requested to be used in projects like 
> >> > >>>> Cassandra-ecosystem, but also non-cassandra projects.  Both users 
> >> > >>>> need to know that a hot fix doesn’t break their build hence why I 
> >> > >>>> propose basic properties you would expect: major versions might 
> >> > >>>> have breaking changes, minor / patch won’t.  For the classes anyone 
> >> > >>>> has talked about moving here, non of them should have issues with 
> >> > >>>> this; we are free to add new methods over time, but removing causes 
> >> > >>>> issues for consumers.
> >> > >>>>
> >> > >>>>> to improve code sharing.
> >> > >>>>
> >> > >>>> Even if you think about this only for cassandra ecosystem, if I 
> >> > >>>> depend on version 0.1.0 and we find a bug so get that fixed and now 
> >> > >>>> we depend on 0.1.10… I shouldn’t expect to deal with breaking 
> >> > >>>> changes.  The mentality of “They’re all internal” as a 
> >> > >>>> justification to not document these assumptions causes me concern 
> >> > >>>> as breaking changes explicitly make it harder for parties to depend 
> >> > >>>> on these classes; breaking changes make is so much harder to “share 
> >> > >>>> code”.
> >> > >>>>
> >> > >>>>> We only care about versioning to ensure we don't break any builds
> >> > >>>>
> >> > >>>> What do you mean by this?  Major versions I am ok with breaking 
> >> > >>>> changes; minor / patch is what I want to avoid.  We can add new 
> >> > >>>> APIs without issue, the concern is only on removal.
> >> > >>>>
> >> > >>>>> and even decide when we upgrade the jar so can spot and fix any 
> >> > >>>>> breakages.
> >> > >>>>
> >> > >>>> If we are upgrading to enable a new JDK change, I wouldn’t expect 
> >> > >>>> users to have to rewrite all their tests, redo all their 
> >> > >>>> collections, etc…. You shouldn’t have to worry about upgrading the 
> >> > >>>> version cross minor / patch versions, as that should impose a no 
> >> > >>>> breaking change rule.
> >> > >>>>
> >> > >>>>
> >> > >>>>> On Aug 14, 2026, at 3:06 PM, Benedict Elliott Smith 
> >> > >>>>> <[email protected]> wrote:
> >> > >>>>>
> >> > >>>>> Why are we defining this at all? They're all internal, this is a 
> >> > >>>>> convenience to improve code sharing. We only care about versioning 
> >> > >>>>> to ensure we don't break any builds, and we have all the builds, 
> >> > >>>>> and even decide when we upgrade the jar so can spot and fix any 
> >> > >>>>> breakages.
> >> > >>>>>
> >> > >>>>> Let's not overcomplicate things, or bind our future selves in red 
> >> > >>>>> tape and regret.
> >> > >>>>>
> >> > >>>>> On 2026/08/14 17:57:40 Josh McKenzie wrote:
> >> > >>>>>> While I read your email I found myself wondering "To what are we 
> >> > >>>>>> referring to when we say 'API'"? ;)
> >> > >>>>>>
> >> > >>>>>> Are you talking about a public interface? Or are you talking 
> >> > >>>>>> about "any class that's public and any public method within a 
> >> > >>>>>> public class"?
> >> > >>>>>>
> >> > >>>>>> If the latter, my primary theoretical concern is that if we pull 
> >> > >>>>>> in code that has components that are scoped public for 
> >> > >>>>>> cross-package accessibility within-project, promoting those to 
> >> > >>>>>> "public by default" immediately calcifies their interface whether 
> >> > >>>>>> we intend for that to be consumed or not. Basically, we don't 
> >> > >>>>>> have an interim scope layer between "package private" and 
> >> > >>>>>> "public" that corresponds to "project public". In theory the post 
> >> > >>>>>> JDK9 modularity kind of provides that but then everyone just 
> >> > >>>>>> add-opens bulldozes across things (the joys of legacy code...).
> >> > >>>>>>
> >> > >>>>>> I think "Any interface that's public is a public API" is pretty 
> >> > >>>>>> obvious to maintainers and users and good. I'm also good with 
> >> > >>>>>> "anything public is an API unless otherwise documented" and we 
> >> > >>>>>> add a simple annotation like @INTERNAL 
> >> > >>>>>> <https://github.com/apiguardian-team/apiguardian/blob/main/src/main/java/org/apiguardian/api/API.java#L87>
> >> > >>>>>>  from API Guardian to basically say "yeah, this is public, but 
> >> > >>>>>> it's not intended for public consumption" (I think we should roll 
> >> > >>>>>> our own to match our proposed lifecycles but that's a clear 
> >> > >>>>>> example of the idea).
> >> > >>>>>>
> >> > >>>>>> I'm worried about the approach of "Any public method in a public 
> >> > >>>>>> class is considered public API and you can't change it". I'd 
> >> > >>>>>> prefer we start with a more constrained surface area we commit to 
> >> > >>>>>> as being an API and widen it later if we find there's a need; 
> >> > >>>>>> it's much harder to go in the other direction.
> >> > >>>>>>
> >> > >>>>>> On Fri, Aug 14, 2026, at 1:24 PM, David Capwell wrote:
> >> > >>>>>>> Josh and I talked about this offline and not perfectly in-sync 
> >> > >>>>>>> so would be good to get other peoples views
> >> > >>>>>>>
> >> > >>>>>>> My take is that if you are adding the API to this shared repo we 
> >> > >>>>>>> need to care about backwards compatibility so things should be 
> >> > >>>>>>> PUBLIC by default (anything that is java public is part of the 
> >> > >>>>>>> public interface and breaking changes are not allowed without a 
> >> > >>>>>>> long enough deprecation window similar to Cassandra’s.). I think 
> >> > >>>>>>> Josh is in favor of using a annotation to mark that a API is 
> >> > >>>>>>> public, but without custom tooling I don’t think anyone will 
> >> > >>>>>>> notice and then we will get to a effectively public state and 
> >> > >>>>>>> breaking changes will be a nightmare to deal with for the 
> >> > >>>>>>> community.  So if you want to post the API here, it should be 
> >> > >>>>>>> stable and we shouldn’t be putting APIs that have not been 
> >> > >>>>>>> fleshed out first.
> >> > >>>>>>>
> >> > >>>>>>>> On Aug 7, 2026, at 8:16 AM, Josh McKenzie 
> >> > >>>>>>>> <[email protected]> wrote:
> >> > >>>>>>>>
> >> > >>>>>>>> One thing worth immediately calling out that we might want to 
> >> > >>>>>>>> split out: we *could* do this work in Ant.
> >> > >>>>>>>>
> >> > >>>>>>>> It would be somewhat more imperative and brittle: we'd 
> >> > >>>>>>>> explicitly orchestrate the build ordering in Ant, while relying 
> >> > >>>>>>>> on the Gradle build inside Accord for its cassandra-utils 
> >> > >>>>>>>> dependency resolution / source substitution. That leaves us 
> >> > >>>>>>>> with a somewhat more complicated mixed Ant/Gradle build 
> >> > >>>>>>>> relationship but it's entirely workable for an interim time.
> >> > >>>>>>>>
> >> > >>>>>>>> So if the Gradle migration is a sticking point, we can break 
> >> > >>>>>>>> that out into a separate discussion and CEP rather than making 
> >> > >>>>>>>> it part of CEP-65.
> >> > >>>>>>>>
> >> > >>>>>>>> Doing so would mean retaining and extending some of the 
> >> > >>>>>>>> complexity in our existing build system that a future migration 
> >> > >>>>>>>> could remove, but it's not a crushing amount of additional 
> >> > >>>>>>>> complexity. The benefit of doing that work here with this CEP 
> >> > >>>>>>>> is that we have one more concrete build need providing a reason 
> >> > >>>>>>>> to move toward a unified build stack, and it fits the "clean 
> >> > >>>>>>>> things up and refactor as you're working on things that could 
> >> > >>>>>>>> benefit from that work" approach many have argued for in the 
> >> > >>>>>>>> past on the project.
> >> > >>>>>>>>
> >> > >>>>>>>> On Fri, Aug 7, 2026, at 10:58 AM, Josh McKenzie wrote:
> >> > >>>>>>>>> As per the previous ML thread: [DISCUSS] Forking Cassandra 
> >> > >>>>>>>>> utilities into a separately released library 
> >> > >>>>>>>>> <https://lists.apache.org/thread/7kllp45vvonsg7ggzxpz39c5kdcy7r6g>,
> >> > >>>>>>>>>  David and I put together a draft of what we discussed and 
> >> > >>>>>>>>> worked through some implications and requirements that came up 
> >> > >>>>>>>>> as we tried to nail things down.
> >> > >>>>>>>>>
> >> > >>>>>>>>> The goal here is to provide a material backstop to continue 
> >> > >>>>>>>>> our discussion and version it. As with all CEP DISCUSS 
> >> > >>>>>>>>> threads, this is very fluid and none of it should be taken as 
> >> > >>>>>>>>> settled or an implicit mandate. Let's see if we can make some 
> >> > >>>>>>>>> progress on this long-standing pain point in our ecosystem.
> >> > >>>>>>>>>
> >> > >>>>>>>>> CEP-65 DRAFT: link 
> >> > >>>>>>>>> <https://cwiki.apache.org/confluence/spaces/CASSANDRA/pages/446071230/CEP-65+cassandra-utils+-+A+shared+utility+library+for+the+cassandra+ecosystem+DRAFT>
> >> > >>>>>>>>>
> >> > >>>>>>>>> *Why You Should Read This Draft:*
> >> > >>>>>>>>> 1.  Build system impact: we need a parent project and one of 
> >> > >>>>>>>>> its submodule to depend on another submodule. We're proposing 
> >> > >>>>>>>>> freezing ant's API surface area, maintaining that into 
> >> > >>>>>>>>> perpetuity, and moving to gradle going forward.
> >> > >>>>>>>>> 2. Branching model: read the draft to see what "One Branch to 
> >> > >>>>>>>>> Rule Them All" means.
> >> > >>>>>>>>> 3. API Lifecycle: Is @BETA/@STABLE/@DEPRECATED enough? Do we 
> >> > >>>>>>>>> need a @PRIVATE?
> >> > >>>>>>>>> 4. To Release or Not To Release: we're proposing consumers 
> >> > >>>>>>>>> embed this as a submodule initially to minimize friction in 
> >> > >>>>>>>>> moving shared code into a shared space.
> >> > >>>>>>>>> We have 1 outstanding unanswered question we didn't come up 
> >> > >>>>>>>>> with an opinionated proposal for:
> >> > >>>>>>>>>
> >> > >>>>>>>>> What should unannotated methods and classes in the library be 
> >> > >>>>>>>>> considered by potential consumers? @PRIVATE? @PUBLIC? Should 
> >> > >>>>>>>>> we lint and fail on any class without a top-level annotation 
> >> > >>>>>>>>> forcing us to make a choice on our dev list [DISCUSS] threads 
> >> > >>>>>>>>> whenever we bring in new things?
> >> > >>>>>>>>>
> >> > >>>>>>>>> There's no timeline on this thread; let's keep turning the 
> >> > >>>>>>>>> crank on this until we've hit our pareto-polish frontier. ;)
> >> > >>>>>>>>>
> >> > >>>>>>>>> ~Josh
> >> > >>>>>>>>>
> >> > >>>>>>>>>
> >> > >>>>>>>>
> >> > >>>>>>
> >> > >>>>
> >> > >>>>
> >> > >>>
> >> > >>
> >> >
> 

Reply via email to