fix(cassandra): publish required service schemas#439
Conversation
📝 WalkthroughWalkthroughAdds Cassandra keyspace, role, UDT, table, index, lock, and liveness migrations for ChangesCassandra schema publication
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
🌿 Preview your docs: https://nvidia-preview-fix-publish-cassandra-schemas.docs.buildwithfern.com/nvcf |
Add the nvct_api and nvcf_autoscaler migrations to the GitHub build source and require every documented schema inventory entry to include its three baseline migration files. Fixes #438 Signed-off-by: Stephanie Baum <sbaum@nvidia.com>
004e3fb to
f8f6fe1
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@migrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sql`:
- Around line 7-8: Replace the direct system_auth role_members INSERT and
roles.member_of UPDATE in
migrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sql and
migrations/cassandra/keyspaces/nvct_api/02_init_roles.up.sql with Cassandra’s
supported GRANT role-membership statement, granting each application access role
to its corresponding application role.
In `@migrations/cassandra/keyspaces/nvcf_autoscaler/03_init_tables.up.sql`:
- Around line 1-3: Resolve the schema/design inconsistency by either restoring
the archived columns in
migrations/cassandra/keyspaces/nvcf_autoscaler/03_init_tables.up.sql#L1-L3 or
documenting the approved account_id/nca_id replacement and migration impact.
Update
docs/superpowers/specs/2026-07-24-publish-cassandra-schemas-design.md#L37-L41 to
replace the “only expression changes” claim, and revise `#L48-L49` so verification
explicitly covers the approved schema differences.
In `@migrations/cassandra/keyspaces/nvct_api/03_init_tables.up.sql`:
- Around line 1-2: Update the provenance comment’s version reference for the
nvct_api schema from v1.2.4 to v1.5.2, keeping the existing source path and
canonical-schema wording unchanged.
In `@migrations/cassandra/tests/test-execute-sqls.sh`:
- Around line 19-24: Validate that schema_inventory produced by the README
parsing command is non-empty before entering the keyspace_name loop. If no
schema names were parsed, exit with a failure status and a clear diagnostic;
otherwise preserve the existing loop behavior.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 408041be-40e2-4d78-93dc-8aa481992b34
📒 Files selected for processing (8)
docs/superpowers/specs/2026-07-24-publish-cassandra-schemas-design.mdmigrations/cassandra/keyspaces/nvcf_autoscaler/01_init_keyspace.up.sqlmigrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sqlmigrations/cassandra/keyspaces/nvcf_autoscaler/03_init_tables.up.sqlmigrations/cassandra/keyspaces/nvct_api/01_init_keyspace.up.sqlmigrations/cassandra/keyspaces/nvct_api/02_init_roles.up.sqlmigrations/cassandra/keyspaces/nvct_api/03_init_tables.up.sqlmigrations/cassandra/tests/test-execute-sqls.sh
| INSERT INTO system_auth.role_members (role, member) VALUES ('nvcf_autoscaler_app_access', 'nvcf_autoscaler_app_v0'); | ||
| UPDATE system_auth.roles SET member_of = member_of + {'nvcf_autoscaler_app_access'} where role = 'nvcf_autoscaler_app_v0'; |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '== AGENTS =='
find .. -name AGENTS.md -print
echo '== Relevant files =='
for f in \
migrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sql \
migrations/cassandra/keyspaces/nvct_api/02_init_roles.up.sql \
migrations/cassandra/keyspaces/nvcf_autoscaler/03_init_tables.up.sql \
migrations/cassandra/keyspaces/nvct_api/03_init_tables.up.sql \
docs/superpowers/specs/2026-07-24-publish-cassandra-schemas-design.md
do
if [ -f "$f" ]; then
echo "--- $f ($(wc -l < "$f") lines) ---"
cat -n "$f" | sed -n '1,220p'
fi
done
echo '== Search for role management guidance =='
rg -n "GRANT ROLE|role_members|system_auth|member_of|role management|GRANT .* TO" migrations docs -SRepository: NVIDIA/nvcf
Length of output: 15668
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '== 02_init_roles.up.sql files =='
for f in migrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sql migrations/cassandra/keyspaces/nvct_api/02_init_roles.up.sql; do
echo "--- $f ---"
cat -n "$f"
done
echo '== Cassandra schema docs mentions =='
rg -n "system_auth|role_members|member_of|GRANT ROLE|CREATE ROLE|REVOKE ROLE|CQL security|roles" docs migrations -S
echo '== file sizes =='
wc -l migrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sql migrations/cassandra/keyspaces/nvct_api/02_init_roles.up.sqlRepository: NVIDIA/nvcf
Length of output: 12436
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '== AGENTS under repo =='
for f in AGENTS.md infra/cassandra/AGENTS.md migrations/cassandra/AGENTS.md migrations/cassandra/keyspaces/AGENTS.md; do
if [ -f "$f" ]; then
echo "--- $f ($(wc -l < "$f") lines) ---"
cat -n "$f" | sed -n '1,220p'
fi
done
echo '== migrations/cassandra/README.md relevant lines =='
if [ -f migrations/cassandra/README.md ]; then
cat -n migrations/cassandra/README.md | sed -n '130,180p'
fi
echo '== search for GRANT ROLE / role_members in docs and migrations =='
rg -n "GRANT ROLE|role_members|system_auth\.roles|system_auth\.role_members|member_of =" migrations/cassandra docs -SRepository: NVIDIA/nvcf
Length of output: 18466
🌐 Web query:
Apache Cassandra role management GRANT ROLE system_auth.role_members documentation
💡 Result:
In Apache Cassandra, the GRANT ROLE statement is used to assign one role to another, establishing a hierarchical relationship where the grantee inherits the permissions of the granted role [1][2]. Role management is handled by the IRoleManager interface, and the default implementation, CassandraRoleManager, persists this information within the system_auth keyspace [3][4][5]. Specifically, the system_auth.role_members table acts as the lookup table that tracks these role-to-role grants [6][5][7]. Key points regarding GRANT ROLE and system_auth.role_members: 1. Syntax: The CQL statement follows the format GRANT role_name TO role_name [1][8]. 2. Functionality: Roles are modeled as a directed acyclic graph (DAG) [1][2]. When a role is granted to another, the grantee acquires all permissions associated with the granted role [1][2]. Circular grants are strictly prohibited by the system [1][8]. 3. Data Storage: The system_auth.role_members table is defined with the following schema: CREATE TABLE system_auth.role_members ( role text, member text, PRIMARY KEY(role, member)); This table stores the mapping of roles to their members (the roles that have been granted to them) [6][5]. While the GRANT ROLE command provides the primary interface for managing these relationships, the system_auth.role_members table is the internal persistent storage mechanism used by the default CassandraRoleManager [4][5]. Direct modification of system tables is generally discouraged in favor of using standard CQL commands [1][9].
Citations:
- 1: https://cassandra.apache.org/doc/5.0.8/cassandra/developing/cql/security.html
- 2: https://cassandra.apache.org/doc/4.1/cassandra/cql/security.html
- 3: https://javadoc.io/static/org.apache.cassandra/cassandra-all/4.1.7/org/apache/cassandra/auth/CassandraRoleManager.html
- 4: https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/auth/CassandraRoleManager.java
- 5: https://axonops.com/docs/data-platforms/cassandra/cql/security/rbac/
- 6: https://fossies.org/dox/apache-cassandra-5.0.8-src/AuthKeyspace_8java_source.html
- 7: https://docs.datastax.com/en/cql/hcd/secure/secure-system-tables.html
- 8: https://murukeshm.github.io/cassandra/3.11.2/cql/security.html
- 9: https://cassandra.apache.org/doc/latest/cassandra/developing/cql/cql_singlefile.html
Use GRANT ... TO ... for role membership.
Replace the system_auth.role_members insert and system_auth.roles.member_of update in both migrations with Cassandra’s supported role-grant statement.
migrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sqlmigrations/cassandra/keyspaces/nvct_api/02_init_roles.up.sql
GRANT <role> TO <role> is the supported CQL path; writing system_auth directly ties the migration to Cassandra internals.
📍 Affects 2 files
migrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sql#L7-L8(this comment)migrations/cassandra/keyspaces/nvct_api/02_init_roles.up.sql#L7-L8
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@migrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sql` around
lines 7 - 8, Replace the direct system_auth role_members INSERT and
roles.member_of UPDATE in
migrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sql and
migrations/cassandra/keyspaces/nvct_api/02_init_roles.up.sql with Cassandra’s
supported GRANT role-membership statement, granting each application access role
to its corresponding application role.
Source: MCP tools
| -- Canonical schema for nvcf_autoscaler keyspace. | ||
| -- Pinned to the upstream nvcf_autoscaler schema at migration version 9. | ||
| -- account_id (TEXT) consolidates upstream nca_id_string from migrations 02-09. nca_id UUID dropped (NCA IDs are not UUIDs and the column was unused). |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Align the schema baseline and design record before publication.
The SQL comments describe a column-level schema change, while the design record promises that only replica-count templating changes. Resolve this contradiction by either restoring the archived schema or explicitly approving and documenting the compatibility impact.
migrations/cassandra/keyspaces/nvcf_autoscaler/03_init_tables.up.sql#L1-L3: restore the archived columns or document the approved field replacement and migration impact.docs/superpowers/specs/2026-07-24-publish-cassandra-schemas-design.md#L37-L41: update the “only expression changes” compatibility claim.docs/superpowers/specs/2026-07-24-publish-cassandra-schemas-design.md#L48-L49: update the verification requirement so it reflects the approved schema differences.
📍 Affects 2 files
migrations/cassandra/keyspaces/nvcf_autoscaler/03_init_tables.up.sql#L1-L3(this comment)docs/superpowers/specs/2026-07-24-publish-cassandra-schemas-design.md#L37-L41docs/superpowers/specs/2026-07-24-publish-cassandra-schemas-design.md#L48-L49
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@migrations/cassandra/keyspaces/nvcf_autoscaler/03_init_tables.up.sql` around
lines 1 - 3, Resolve the schema/design inconsistency by either restoring the
archived columns in
migrations/cassandra/keyspaces/nvcf_autoscaler/03_init_tables.up.sql#L1-L3 or
documenting the approved account_id/nca_id replacement and migration impact.
Update
docs/superpowers/specs/2026-07-24-publish-cassandra-schemas-design.md#L37-L41 to
replace the “only expression changes” claim, and revise `#L48-L49` so verification
explicitly covers the approved schema differences.
| -- Canonical schema for nvct_api keyspace. | ||
| -- Reference: nvcf/nvct-api v1.2.4 local_env/cassandra/schema/0001_initial_schema.cql |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate guidance and relevant files
printf '\n== AGENTS files ==\n'
find .. -name AGENTS.md -print
printf '\n== Relevant file listings ==\n'
git ls-files 'migrations/cassandra/keyspaces/**' | sed -n '1,120p'
printf '\n== README pin references ==\n'
rg -n 'nvct_api|v1\.5\.2|v1\.2\.4|nvct-api' migrations/cassandra/keyspaces/README.md migrations/cassandra/keyspaces/nvct_api/03_init_tables.up.sql || true
printf '\n== File sizes ==\n'
wc -l migrations/cassandra/keyspaces/README.md migrations/cassandra/keyspaces/nvct_api/03_init_tables.up.sqlRepository: NVIDIA/nvcf
Length of output: 6104
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the small relevant sections with line numbers
printf '\n== README excerpt ==\n'
cat -n migrations/cassandra/keyspaces/README.md | sed -n '1,220p'
printf '\n== SQL excerpt ==\n'
cat -n migrations/cassandra/keyspaces/nvct_api/03_init_tables.up.sql | sed -n '1,220p'Repository: NVIDIA/nvcf
Length of output: 10620
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect nearby documentation for how the pinned source revisions are tracked.
rg -n 'v1\.5\.2|v1\.2\.4|nvct_api|schema/0001_initial_schema\.cql|design record|pin' migrations/cassandra/keyspaces -g '!**/*.png'Repository: NVIDIA/nvcf
Length of output: 3684
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the exact README entry and any related design record references.
python3 - <<'PY'
from pathlib import Path
files = [
Path('migrations/cassandra/keyspaces/README.md'),
Path('migrations/cassandra/keyspaces/nvct_api/03_init_tables.up.sql'),
]
for p in files:
print(f"\n### {p} ###")
text = p.read_text()
for i, line in enumerate(text.splitlines(), 1):
if 'nvct_api' in line or 'v1.5.2' in line or 'v1.2.4' in line or 'schema/0001_initial_schema.cql' in line:
start = max(1, i-3)
end = min(len(text.splitlines()), i+3)
for j in range(start, end+1):
print(f"{j}: {text.splitlines()[j-1]}")
print()
PY
printf '\n== search for design record ==\n'
rg -n 'nvct_api|v1\.5\.2|v1\.2\.4|0001_initial_schema\.cql|design record|upstream schema' . -g '!**/.git/**'Repository: NVIDIA/nvcf
Length of output: 20276
Update the provenance reference in migrations/cassandra/keyspaces/nvct_api/03_init_tables.up.sql:2. The README pins nvct_api to v1.5.2, so the current v1.2.4 label is stale and makes the schema source unclear.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@migrations/cassandra/keyspaces/nvct_api/03_init_tables.up.sql` around lines 1
- 2, Update the provenance comment’s version reference for the nvct_api schema
from v1.2.4 to v1.5.2, keeping the existing source path and canonical-schema
wording unchanged.
| schema_inventory=$( | ||
| # shellcheck disable=SC2016 | ||
| sed -n 's/^| `\([^`]*\)`[[:space:]]*| \[[^]]*\].*$/\1/p' \ | ||
| "${keyspaces}/README.md" | ||
| ) | ||
| for keyspace_name in ${schema_inventory}; do |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Fail closed when the schema inventory is empty.
If the README format changes or parsing returns no rows, the loop is skipped and CI reports success without checking any schema. Add an assertion before the loop:
Proposed fix
schema_inventory=$(
sed -n 's/^| `\([^`]*\)`[[:space:]]*| \[[^]]*\].*$/\1/p' \
"${keyspaces}/README.md"
)
+if [ -z "${schema_inventory}" ]; then
+ fail "schema inventory is empty or malformed"
+fi
for keyspace_name in ${schema_inventory}; do📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| schema_inventory=$( | |
| # shellcheck disable=SC2016 | |
| sed -n 's/^| `\([^`]*\)`[[:space:]]*| \[[^]]*\].*$/\1/p' \ | |
| "${keyspaces}/README.md" | |
| ) | |
| for keyspace_name in ${schema_inventory}; do | |
| schema_inventory=$( | |
| # shellcheck disable=SC2016 | |
| sed -n 's/^| `\([^`]*\)`[[:space:]]*| \[[^]]*\].*$/\1/p' \ | |
| "${keyspaces}/README.md" | |
| ) | |
| if [ -z "${schema_inventory}" ]; then | |
| fail "schema inventory is empty or malformed" | |
| fi | |
| for keyspace_name in ${schema_inventory}; do |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@migrations/cassandra/tests/test-execute-sqls.sh` around lines 19 - 24,
Validate that schema_inventory produced by the README parsing command is
non-empty before entering the keyspace_name loop. If no schema names were
parsed, exit with a failure status and a clear diagnostic; otherwise preserve
the existing loop behavior.
TL;DR
Publish the
nvct_apiandnvcf_autoscalerCassandra schemas so fresh self-managed installations create every documented keyspace. Add an inventory regression test so a schema listed in the migration README cannot be omitted from future images.Additional Details
Why
The GitHub migration source listed both keyspaces in its schema inventory but did not contain their migration directories. The migration job could therefore complete successfully while required service keyspaces were absent.
What changed
nvct_api.nvcf_autoscaler.${REPLICA_COUNT}substitution supported by the current migration entrypoint.01_init_keyspace.up.sql,02_init_roles.up.sql, and03_init_tables.up.sql.Customer Release Notes
Fresh self-managed installations now create the Cassandra schemas required by the task and function autoscaler services.
Plan Summary
The migration image gains two keyspaces, their application roles, and their canonical tables and types. Existing migration discovery applies the files without deployment wiring changes.
Usage
No operator action is required beyond using an image containing this change for a fresh installation.
Testing
sh migrations/cassandra/tests/test-execute-sqls.shsh -n migrations/cassandra/tests/test-execute-sqls.shshellcheck migrations/cassandra/tests/test-execute-sqls.shgit diff --check origin/main...HEADQA is recommended on a fresh supported Cassandra deployment to confirm all seven documented keyspaces are created. No local cluster was mutated during validation.
Notes
The inventory check is README-driven so the documented schema source list remains the publication contract.
References
Related Pull Requests
None.
Dependencies
None. No license review or NOTICE update is required.
For the Reviewer
Please focus on the schema fidelity and the README-driven inventory check in
migrations/cassandra/tests/test-execute-sqls.sh.For QA
Run the migration image against a fresh supported Cassandra deployment and confirm all keyspaces listed in
migrations/cassandra/keyspaces/README.mdare present.Issues
Fixes #438
Checklist
Summary by CodeRabbit
New Features
Tests