[settings-naming] Normalize ingestor DB/path env vars to TRACEBLOC_ prefix - #587
[settings-naming] Normalize ingestor DB/path env vars to TRACEBLOC_ prefix#587aptracebloc wants to merge 2 commits into
Conversation
…refix Read DB_USER/DB_PASSWORD/DB_NAME and SRC_PATH/LABEL_FILE alias-first via a new _read_env_alias/_require_env: the canonical TRACEBLOC_-prefixed names win, the bare names stay a deprecated read-side alias (remove_by 2026-12-31). A present- but-empty value resolves as present (is-not-None), so a blank canonical wins over a stale legacy value -- an optional field returns the blank as-is, while a required credential fails fast instead of silently authenticating with the legacy secret. The runtime_env contract keeps DB_USER/DB_PASSWORD as the required names the spawner (jobs-manager) injects; the required-name flip to the canonical is a coordinated phase-2 step, so _require_env takes the injected name as arg 0 (what the contract test pins) and reads the canonical alias ahead of it. Docs (ingestor-job.yaml, Readme, e2e + template READMEs) moved to the canonical spelling with the deprecated-alias note. data-ingestors#585. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…g.py (Bugbot) The schema's `aliases` and _require_env's `canonical` argument were two hand-kept copies of the same alias-first names, with only arg 0 (the required `name`) pinned. Extend the AST reader to also capture the canonical alias per call, and assert the schema `aliases` set equals the set the reader actually accepts — in both directions. Over-claiming (contract lists a name the reader ignores) and under-claiming (reader accepts a name the contract omits) now both fail the contract test, so a spawner trusting `aliases` can never drift from the reader. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
bugbot run |
|
bugbot run |
|
Addressed the Bugbot finding ("Aliases lack bidirectional contract pins"): extended The AST reader now captures both args per — drafted with Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 2cc6360. Configure here.
|
|
||
| > The ingestor reads its DB env alias-first (RFC-0076 settings-naming), so the | ||
| > canonical `TRACEBLOC_DB_*` spellings above work. The direct-connect contract | ||
| > tests (`test_*_e2e.py`) still read the legacy `DB_USER`/`DB_PASSWORD`/`DB_NAME` |
There was a problem hiding this comment.
The note says conftest backfills to the same root defaults, but conftest.py backfills via os.environ.get("DB_USER", "root") (lines 81-83) — that only lands on root when DB_USER/DB_PASSWORD are unset. A user who follows the new guidance and sets non-root creds via the canonical names (TRACEBLOC_DB_USER=myuser TRACEBLOC_DB_PASSWORD=...) leaves the bare DB_USER/DB_PASSWORD unset, so the ingestor-path connects as myuser while the direct-connect test_*_e2e.py tests connect as root — a silent split that didn't exist before this PR (both sides used the same DB_* names). Consider having conftest read TRACEBLOC_DB_* alias-first too (matching the ingestor), or noting the example only holds for the root container defaults.
saqlainsyed007
left a comment
There was a problem hiding this comment.
Approving. Clean, tightly-scoped RFC-0076 settings-naming migration for the ingestor's DB/path env surface — and correctly a shim, not a hard-cut: _read_env_alias reads the canonical TRACEBLOC_* name first and falls back to the bare deprecated name (remove_by: 2026-12-31), so no reader or deployment breaks in lockstep.
What I verified:
- Migration is alias-first (
is not None, not truthiness): a present-but-blank canonical wins over a stale legacy value — returned as-is for optional fields, and correctly fail-fast in_require_envfor the required credentials so a blank never silently authenticates with a legacy secret. Well-covered by the new parametrized tests. - Var-SETTING side moves in this same PR:
ingestor-job.yamlsets theTRACEBLOC_*names, docs/templates swept, deprecation notes added. No deploy mismatch. - No old-name reader left behind in a breaking way. The e2e
test_*_e2e.py/conftest.pystill use the bareDB_*names — explicitly deferred as phase-2 (setter side moves with the spawner flip), and safe meanwhile because the alias resolves both. runtime_env.v1.jsonkeepsDB_USER/DB_PASSWORDas the required contract names (reader-before-writer) and documents the canonical asaliases; the new AST↔schematest_declared_aliases_match_what_the_reader_acceptspins the two copies bidirectionally.
CI fully green (pytest 3.11/3.12, e2e real MySQL, Bugbot, quality suite). One low-severity docs nit posted inline on e2e/README.md (the "same root defaults" note only holds for the root example) — non-blocking, overlaps the phase-2 deferral already named in the PR body.
What
RFC-0076 settings-naming for the data-ingestors env surface (data-ingestors#585, part of the backend#3391 epic). The ingestor now reads its own DB and path env vars alias-first: the canonical
TRACEBLOC_-prefixed name wins, the bare name keeps working as a deprecated read-side alias (remove_by: 2026-12-31).Old → new (canonical is read first; the bare name is a deprecated alias)
DB_USERTRACEBLOC_DB_USERDB_PASSWORDTRACEBLOC_DB_PASSWORDDB_NAMETRACEBLOC_DB_NAMEtraining_test_datasets)SRC_PATHTRACEBLOC_SRC_PATH"")LABEL_FILETRACEBLOC_LABEL_FILE"")Not renamed here:
MYSQL_HOST/MYSQL_PORT(the stock MySQL-image / docker-entrypoint contract, not ours) andTABLE_NAME(cross-repo ingest wire contract; its rename is a B4 decision — deferred).Blank-handling
_read_env_aliasresolves onis not None, not truthiness: an explicitly-set-empty canonical (TRACEBLOC_DB_NAME="") is a present value that wins over a stale legacy name or the default — restoring the pre-PRos.environ.getbehaviour and preserving an explicit blank for the caller's own guard. An optional field returns the blank as-is; a required credential's_require_envstill fails fast on the blank, so a blank required credential fails loudly rather than silently authenticating with a stale legacy secret. (Matches what backend/client-runtime settled on: "preserve present-but-blank for the caller's guard".)runtime_env contract stays legacy-required until the phase-2 spawner flip
runtime_env.v1.json'srequired[].namestaysDB_USER/DB_PASSWORD— the name jobs-manager actually injects today. The addedaliases: ["TRACEBLOC_DB_USER"]/["TRACEBLOC_DB_PASSWORD"]documents the canonical the reader also accepts. Declaring the canonical name required before the spawner injects it would be a reader-before-writer violation and would falsely fail the backend spawner-contract check. Flipping the required name to the canonical is a coordinated phase-2 step (when the spawner injects the canonical); accordingly_require_envtakes the injected name as arg 0 (what the AST contract test pins) and reads the canonical alias ahead of it. Contractversionis unchanged.Docs swept to the canonical spelling (+ deprecated-alias note)
Readme.md,ingestor-job.yaml— the stale "bareDB_USER/DB_PASSWORDbelow still work" comment is reworded: the env block now setsTRACEBLOC_DB_*, and the bare names remain read-side aliases (not set in this file).tabular_classification,tabular_regression,time_series_classification,time_series_forecasting,time_to_event_prediction(plus the previously-updatedcausal_language_modeling/embeddings/masked_language_modeling/seq2seq).e2e/README.md.Deferred follow-ups (not in this PR)
test_image_lookup_contract_e2e.py,test_semseg_client_contract_e2e.py,test_content_compare_e2e.py,test_characterization.py,test_database_e2e.py,test_ingest_e2e.py) connect to MySQL viaos.environ["DB_USER"]directly, ande2e/conftest.pystill injects the legacyDB_*names. Latent — breaks only when the alias is dropped; the conftest is the phase-2 setter side and moves with the spawner flip.TABLE_NAMErename — cross-repo ingest wire contract; its eventual name is a B4 decision (already deferred).Verification
DB_NAMEand (fail-fast) forDB_USER/DB_PASSWORD, and the reconciled runtime_env contract.black --checkandruff check(reporuff.toml, pinned ruff 0.15.20) clean.__version__0.8.21 pending vs v0.8.20 released), no bump required.Closes #585
Part of tracebloc/backend#3391
🤖 Generated with Claude Code
Note
Medium Risk
Changes how MySQL credentials and ingest paths are read from the environment, including edge cases when both old and new names are set; backward-compatible aliases limit breakage, but mis-set blank canonical vars can fail startup where legacy secrets used to work.
Overview
Implements RFC-0076 settings-naming (data-ingestors#585): the ingestor now resolves DB and path settings alias-first, preferring
TRACEBLOC_DB_USER,TRACEBLOC_DB_PASSWORD,TRACEBLOC_DB_NAME,TRACEBLOC_SRC_PATH, andTRACEBLOC_LABEL_FILE. Legacy names (DB_*,SRC_PATH,LABEL_FILE) still work until 2026-12-31.Configgains_read_env_aliasand extends_require_env(required_name, canonical)so canonical values win when both are set; a present-but-empty canonical overrides a legacy value (optional fields keep""; required creds still fail fast instead of falling back to a stale secret).runtime_env.v1.jsondocumentsaliasesfor the two required credentials whilerequired.namestaysDB_USER/DB_PASSWORDuntil jobs-manager emits the prefixed names (phase 2). Contract tests now pin alias sets againstconfig.pyvia AST.Docs and samples (
Readme.md,ingestor-job.yaml, template READMEs,e2e/README.md) switch to theTRACEBLOC_*spellings with deprecation notes. Unit tests cover alias precedence, blank-canonical behavior, and updatedclean_envvar lists.Reviewed by Cursor Bugbot for commit 2cc6360. Bugbot is set up for automated code reviews on this repo. Configure here.