Skip to content

narratives: drop the cdc backend, and the deploy.sh shrink that follo… - #476

Open
ddebasmita-lab wants to merge 4 commits into
datacommonsorg:narratives-devfrom
ddebasmita-lab:narratives/drop-cdc-backend
Open

ddebasmita-lab wants to merge 4 commits into
datacommonsorg:narratives-devfrom
ddebasmita-lab:narratives/drop-cdc-backend

Conversation

@ddebasmita-lab

@ddebasmita-lab ddebasmita-lab commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Overview

DATA_BACKEND becomes dcp or none. This drops the self-hosted Cloud SQL
data plane (cdc) and everything that existed only to serve it.

Cloud SQL was the reason. There is no connection-pool sizing anywhere in the
Terraform, the default tier is a shared-core db-g1-small, and Cloud Run
concurrency is high enough that MySQL returned "too many connections" rather
than merely getting slow. Spanner has no fixed connection ceiling, no NL server
to run alongside it, managed ingestion, and a Mixer that defaults to stale
reads, so ingestion causes no downtime.

The app plane does not change. It receives a data-plane URL and an auth mode,
and it has never cared which kind of plane is on the other end.

Changes Made

Removed with the cdc backend

  • Cloud SQL instance, database and user; the data bucket; the ingest Job
  • The data-plane Cloud Run service and the app-to-data invoker binding
  • image/ and sample-data/
  • promote-image.yaml, which existed only to mirror
    datacommons-services:stable
  • 18 Terraform variables nothing could reach
  • The <instance>-runtime service account and its seven IAM bindings. That was
    the data-plane container's identity — cloudsql.client and objectAdmin on
    the data bucket — and no app-plane container has ever needed it.
  • MAPS_API_KEY had the same single consumer, so supplying one now warns
    instead of storing a secret nothing reads.

deploy.sh

Refactored deploy.sh with no behavior changes by removing dead code and extracting lines of non-deploy flags (--preflight, --destroy, --config-only, --bootstrap-secrets) into sourced scripts under deploy/modes/.

…wed it

Ported from the source repo, where they are e02ac6f, ffd014c, ec1d4ce and
710b874. Taken as one commit because the second and third only make sense
after the first.

DATA_BACKEND is now dcp or none. Cloud SQL was the reason: no connection-pool
sizing anywhere in the Terraform, a shared-core db-g1-small default tier, and
Cloud Run concurrency high enough that MySQL failed with "too many connections"
rather than merely slow queries. Spanner has no fixed connection ceiling, no NL
server to run, managed ingestion, and a Mixer that defaults to stale reads so
ingestion causes no downtime.

Removed: the Cloud SQL instance, database and user; the data bucket; the ingest
Job; the data-plane service and the app-to-data invoker binding; image/ and
sample-data/; promote-image, which existed only to mirror
datacommons-services:stable; and 18 Terraform variables nothing could reach.
Also the "<instance>-runtime" service account and its seven IAM bindings --
that was the data-plane container's identity, cloudsql.client and objectAdmin
on the data bucket, and no app-plane container has ever needed it. MAPS_API_KEY
had the same single consumer, so supplying one now warns rather than storing a
secret nothing reads.

Kept deliberately. Direct VPC egress, whose derived default was is_cdc: a DCP
plane can be a private service with internal ingress, which is what VPC egress
is for, and that plane is provisioned elsewhere so its ingress is not knowable
from here. MCP 1.2.x handling in the agent, which is payload-shape handling
rather than cdc plumbing -- nothing guarantees every DCP instance serves 1.3.x.
The "-datacommons" and "-data-ingest" suffixes in check-state-owner.py, because
a state file written before this still contains those resources, and destroying
one of those states is the case that guard exists to catch.

deploy.sh rejects DATA_BACKEND=cdc with an explanation rather than a bare
validation error: this revision cannot describe those resources, so it cannot
destroy them either, and an instance still on that backend has to be torn down
with the last revision that declared them.

Then a sweep for what nothing uses. The app-plane image shipped two Gemini SDKs
it never imported -- the agent calls Gemini over REST with requests -- and
between them google-genai and google-generativeai pulled in httpx, pydantic,
websockets, tqdm and the google-api-python-client stack. requirements drops from
48 packages to 29, and is generated now rather than hand-maintained, which
surfaced two real dependencies of google-cloud-secret-manager that the old
freeze was missing. Six branding keys were declared in the schema, shipped in
every example and read by no code; two of them are worse than clutter, because
analytics.ga_tag_id and extra_css could be set, synced, and silently do nothing.

Then deploy.sh, 1146 lines to 609, no behaviour change. --preflight, --destroy,
--config-only and --bootstrap-secrets are 341 lines that never run during a
deploy, so they move to deploy/modes/ and are sourced -- they still share the
loaded instance.env and the log helpers. Comments go from 266 lines to 115,
each keeping its rule and its consequence and dropping the account of how it was
found. Four lines of dead code go too, and monitoring.googleapis.com is now
enabled: the module creates an alert policy and an uptime check, which works
today only because the API is usually on already and would fail on a fresh
project.

The review fixes already on this branch are untouched -- the utf-8 config read
and write, the urlparse prompt-URL derivation and its tests, and the dcproxy
TODO. README keeps the test_prompt_urls line that came with them.

Verified here after the port: terraform fmt and validate clean; bash -n clean on
deploy.sh, smoke.sh and the four mode files; 45 agent checks across five suites;
108 UI tests in 9 files; tsc --noEmit and vite build clean.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request removes the self-hosted Cloud SQL data plane (the cdc backend) and all of its associated resources, such as the services container, ingest job, and sample data, leaving only the dcp and none backends. It also refactors deploy.sh by modularizing its sub-commands into separate scripts under deploy/modes/ and cleans up unused dependencies in both the Python agent and the React UI. The review feedback identifies a critical bug where the deployment script fails to exit after running preflight checks, an issue with API key validation failing on transient Gemini API errors, a missing curl check in the CLI tool verification, and the omission of vite from the UI's devDependencies after its removal from dependencies.

Comment thread narratives/deploy.sh
Comment on lines 261 to 262
if [ "$PREFLIGHT" = true ]; then
run_preflight

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

If --preflight is specified, the script should exit after running run_preflight instead of continuing to the rest of the deployment. Currently, there is no exit statement, so running ./deploy.sh --preflight will perform the checks and then immediately proceed to execute the full deployment (configuring gcloud, enabling APIs, building images, running Terraform, etc.), which violates the 'create nothing' guarantee of preflight.

Suggested change
if [ "$PREFLIGHT" = true ]; then
run_preflight
if [ "$PREFLIGHT" = true ]; then
run_preflight || exit 1
exit 0
fi

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already handled — deploy.sh does exit. In the current branch it is lines 250-253:

if [ "$PREFLIGHT" = true ]; then
    run_preflight
    exit $?
fi

exit $? propagates run_preflight's status, so a failed check exits non-zero and a clean one exits 0. There were four stray blank lines directly above this block, which is most likely what split the diff hunk and hid the exit from the review; they are gone now.

Comment thread narratives/deploy/modes/bootstrap-secrets.sh
Comment thread narratives/deploy.sh Outdated
Comment on lines 23 to +24
"devDependencies": {
"@tailwindcss/vite": "^4.1.14",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The primary build tool vite was removed from dependencies but was not added to devDependencies. While it might be transitively installed by @tailwindcss/vite or @vitejs/plugin-react, relying on transitive dependencies for your main build tool is risky and can lead to build failures or version mismatches. It should be explicitly declared in devDependencies.

Suggested change
"devDependencies": {
"@tailwindcss/vite": "^4.1.14",
"devDependencies": {
"vite": "^6.2.0",
"@tailwindcss/vite": "^4.1.14",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

vite is already in devDependencies, at line 34 of ui/package.json. This PR moved it there from dependencies, along with @tailwindcss/vite and @vitejs/plugin-react. Applying the suggestion would add a second vite key to the same object.

Two fixes from the review bot on this PR.

bootstrap-secrets.sh validates both API keys with curl, but the early
tool check did not ask for it, so a machine without curl got past the
check and failed mid-run.

The Gemini key check treated every non-200 as a rejected key, so a 429
or a 5xx aborted the deploy and told you the key was bad. Only 400, 401
and 403 say that; everything else now warns and stores the key. This is
what the DC_API_KEY check a few lines above already does.

Also drops four blank lines the mode extraction left behind.
… that

Documents the agent-config document, which had a row in the override
table and nothing else -- no section, no example to copy, and no
mention that schemas/agent-config.example.json exists. The thinking
levels, the model choices, the synthesis-only fallback and the
query_param_key gate were undocumented, and the four steps to turn on
the knowledge base lived only in a _comment inside
defaults/agent-config.json.

Drops provisioning a new DCP data plane. This repository attaches to an
instance that is already running; standing one up is done elsewhere,
with datacommons-cli, and documenting it here implied otherwise.
Attaching is now the single place that explains dcp.

Drops local development, testing, verifying a deployment, design notes
and contributing, leaving the twelve sections a deployer needs. This
removes the test_prompt_urls.py line from the Testing section along
with the section itself.

Fixes what the cdc removal and the deploy-mode extraction left stale:
the intro still offered a Cloud SQL plane, the repository layout listed
promote-image.yaml and a docs/architecture.drawio that no longer exists
and omitted deploy/modes/, and curl was missing from the prerequisites
now that it validates the API keys.

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

Thank you, this is a major cleanup!

Could you separate out the deploy.sh refactoring into a separate, followup PR? This PR is large enough already, and it'll be easier for me to leave dedicated comments if they're in their own PR.

Also, could you reformat the PR description? It looks like an AI agent dumped some thinking but didn't actually fill out the PR template. I especially want to see some instructions for how to test out these changes on my end.

Separately, I find the comments left by the Agent a little too quippy but not as understandable. Let's do some rewriting/refactoring of documentation comments as a followup for later.

Comment thread narratives/agent/requirements.txt Outdated
Comment thread narratives/cloudbuild/deploy-stamp.yaml
Comment thread narratives/cloudbuild/pr-validate.yaml Outdated
Comment on lines -63 to -66
"analytics": {
"ga_tag_id": ""
},
"splash_assets": [],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For my own understanding, why are analytics and splash_assets also removed here??

@ddebasmita-lab ddebasmita-lab Sep 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Because nothing reads them. Neither key is in schemas/branding.schema.json, neither is in defaults/branding.json. They were dead keys carrying empty values (ga_tag_id: "" and splash_assets: []).

"name": "Example Data Commons",
"region": "the world",
"states_term": "regions",
"fiscal_year_start": "01-01"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Also just a question for my own understanding, why is fiscal_year_start being removed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same reason — nothing substitutes it. template_vars is an open map (additionalProperties: {type: string}), so any key you add becomes {{instance.<key>}}. The schema names three by way of documentation: name, region and states_term. Those three are the ones actually referenced by a shipped prompt, in defaults/prompts/synthesis.md lines 4-5.

No prompt has ever contained {{instance.fiscal_year_start}}, so as a default it rendered nowhere. It survives as the example of a user-defined key in agent/tests/test_prompt_rendering.py, which is the role it was really playing. A deployment that wants it adds it to its own config/agent-config.json and references it from its own prompt.

Comment thread narratives/README.md Outdated
Comment thread narratives/deploy/terraform-custom-datacommons/modules/service_account.tf Outdated
Comment thread narratives/deploy/terraform-custom-datacommons/modules/service_account.tf Outdated
Comment on lines +42 to +44
# Resource limits for the app plane. The 4 vCPU / 16Gi pair that used to sit here
# belonged to the cdc services container, whose NL embeddings load needed it; no
# container in this deployment does.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We don't need to mention the old resource limits. Just use "# Resource limits for the app plane" as the comment here.

@ddebasmita-lab ddebasmita-lab Sep 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment thread narratives/deploy.sh Outdated

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should this still say CUSTOM DATA COMMONS at the top?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The product is still Custom Data Commons, so the name stays, but you are right that the line was overblown. It now reads:

# ===========================================================================
# Custom Data Commons — deploy and update one instance.
# ===========================================================================

"UNIFIED ONE-COMMAND DEPLOYER & UPDATE MANAGER" in caps was the part not earning its place.

…rong

Addresses the review.

Asked for directly:
  - requirements.txt: drop the header comment
  - deploy-stamp.yaml: restore the missing step 1 and renumber 3-6 to 2-5
  - pr-validate.yaml: number build-agent as step 4
  - bootstrap-secrets.sh: stop indenting a top-level comment
  - service_account.tf: drop the history of the removed runtime identity
  - new-instance.tfvars.sample: "Resource limits for the app plane"
  - README: drop "(Spanner)" and "No code changes, no branch."
  - deploy.sh: the banner no longer shouts

Comments that were left wrong by the cdc removal:
  - main.tf's header described two Cloud Run services, Cloud SQL, a data
    bucket and MAPS_API_KEY/DB_PASS. There is one service and two secrets.
  - An empty "Cloud SQL" section header, and a "data bucket (created here)"
    header over a lookup of the config bucket, which is not created here.
  - backend.tf documented the state prefix as cdc/<instance>; it is
    custom-datacommons/<instance>.
  - Three pointers to DEPLOY.md and docs/deployment.md, neither of which
    exists. deploy.sh does that work.
  - var.secret_prefix, which no longer exists.

Everywhere else the comments kept the rule and dropped the war story: what
broke, when, and how long it took to find is not what the next reader needs.
Net 225 lines of comment removed, no code touched outside the two README
lines above.

Verified: bash -n on every script, terraform fmt, tsc, 4/4 agent suites,
108/108 vitest, and the UI build.
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