Skip to content

fix(cassandra): publish required service schemas#439

Open
sbaum1994 wants to merge 1 commit into
mainfrom
fix/publish-cassandra-schemas
Open

fix(cassandra): publish required service schemas#439
sbaum1994 wants to merge 1 commit into
mainfrom
fix/publish-cassandra-schemas

Conversation

@sbaum1994

@sbaum1994 sbaum1994 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

TL;DR

Publish the nvct_api and nvcf_autoscaler Cassandra 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

  • Added the three baseline migration files for nvct_api.
  • Added the three baseline migration files for nvcf_autoscaler.
  • Preserved the archived role and table definitions byte for byte.
  • Converted only the two keyspace initializers from the archived Go template to the ${REPLICA_COUNT} substitution supported by the current migration entrypoint.
  • Added a regression check requiring every schema inventory entry to contain 01_init_keyspace.up.sql, 02_init_roles.up.sql, and 03_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.sh
  • sh -n migrations/cassandra/tests/test-execute-sqls.sh
  • shellcheck migrations/cassandra/tests/test-execute-sqls.sh
  • git diff --check origin/main...HEAD
  • Compared all six files with the archived source. Roles and tables match byte for byte; only the approved replica-count transformation differs in the two initializer files.
  • Scanned changed public files for internal tracker IDs, hostnames, and URLs.

QA 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.md are present.

Issues

Fixes #438

Checklist

  • I am familiar with the Contributing Guidelines.
  • I have signed off my commits for Developer Certificate of Origin (DCO) compliance.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

Summary by CodeRabbit

  • New Features

    • Added Cassandra schema initialization for autoscaling and API services.
    • Added service roles, access permissions, and authentication setup.
    • Added tables supporting task orchestration, history tracking, locks, health monitoring, events, and results.
    • Added structured data types and indexing for API task queries.
  • Tests

    • Added validation to ensure each keyspace includes all required migration files.

@sbaum1994
sbaum1994 requested review from a team as code owners July 25, 2026 06:53
@sbaum1994
sbaum1994 requested review from mikeyrcamp and vrv3814 July 25, 2026 06:53
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Cassandra keyspace, role, UDT, table, index, lock, and liveness migrations for nvct_api and nvcf_autoscaler, plus validation that each inventoried keyspace contains the required migration files.

Changes

Cassandra schema publication

Layer / File(s) Summary
Keyspace and role migrations
migrations/cassandra/keyspaces/nvcf_autoscaler/01_init_keyspace.up.sql, migrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sql, migrations/cassandra/keyspaces/nvct_api/01_init_keyspace.up.sql, migrations/cassandra/keyspaces/nvct_api/02_init_roles.up.sql
Creates both keyspaces with replication settings and initializes access and login roles with grants and role membership.
Service schema definitions
migrations/cassandra/keyspaces/nvct_api/03_init_tables.up.sql, migrations/cassandra/keyspaces/nvcf_autoscaler/03_init_tables.up.sql
Defines nvct_api UDTs, task-related tables, an index, and a lock table, alongside autoscaler invocation, history, lock, and healthy-node tables.
Inventory regression coverage
migrations/cassandra/tests/test-execute-sqls.sh
Extracts keyspaces from the schema inventory and fails when any required migration file is missing.

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

Possibly related PRs

  • NVIDIA/nvcf#414: Updates SQL rendering and validation for the migration variables used by these role and keyspace migrations.

Suggested reviewers: vrv3814

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The added keyspace migrations and regression test satisfy #438 by including required schemas and failing when files are missing.
Out of Scope Changes check ✅ Passed The changes stay within the schema-availability fix and its regression test, with no clear unrelated additions.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title follows Conventional Commits and accurately reflects a customer-facing Cassandra schema omission fix.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/publish-cassandra-schemas

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

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>
@sbaum1994
sbaum1994 force-pushed the fix/publish-cassandra-schemas branch from 004e3fb to f8f6fe1 Compare July 25, 2026 06:56

@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: 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

📥 Commits

Reviewing files that changed from the base of the PR and between 68991a9 and 004e3fb.

📒 Files selected for processing (8)
  • docs/superpowers/specs/2026-07-24-publish-cassandra-schemas-design.md
  • migrations/cassandra/keyspaces/nvcf_autoscaler/01_init_keyspace.up.sql
  • migrations/cassandra/keyspaces/nvcf_autoscaler/02_init_roles.up.sql
  • migrations/cassandra/keyspaces/nvcf_autoscaler/03_init_tables.up.sql
  • migrations/cassandra/keyspaces/nvct_api/01_init_keyspace.up.sql
  • migrations/cassandra/keyspaces/nvct_api/02_init_roles.up.sql
  • migrations/cassandra/keyspaces/nvct_api/03_init_tables.up.sql
  • migrations/cassandra/tests/test-execute-sqls.sh

Comment on lines +7 to +8
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';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 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 -S

Repository: 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.sql

Repository: 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 -S

Repository: 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:


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.sql
  • migrations/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

Comment on lines +1 to +3
-- 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).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ 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-L41
  • docs/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.

Comment on lines +1 to +2
-- Canonical schema for nvct_api keyspace.
-- Reference: nvcf/nvct-api v1.2.4 local_env/cassandra/schema/0001_initial_schema.cql

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ 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.sql

Repository: 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.

Comment on lines +19 to +24
schema_inventory=$(
# shellcheck disable=SC2016
sed -n 's/^| `\([^`]*\)`[[:space:]]*| \[[^]]*\].*$/\1/p' \
"${keyspaces}/README.md"
)
for keyspace_name in ${schema_inventory}; do

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 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.

Suggested change
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.

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.

Cassandra migration image omits required service schemas

1 participant