Spaces:
Sleeping
Sleeping
| """Engineering-manager narrator — authors deterministic drift runbooks. | |
| Consumed by the ``read_changelog`` tool. Output is deterministic per | |
| ``DriftConfig`` so tests can assert it character-for-character and the | |
| agent can learn to parse drift kinds from the text. | |
| Entries are concise migration notes: what changed, why the old query | |
| breaks, how to adapt, and what to validate before submission. | |
| """ | |
| from __future__ import annotations | |
| from typing import TYPE_CHECKING | |
| if TYPE_CHECKING: | |
| from scenarios.base import DriftConfig | |
| def _sentence(prefix: str, body: str) -> str: | |
| return f"[changelog] {prefix} {body}".strip() | |
| def author_changelog(drift_config: DriftConfig) -> str: | |
| kind = drift_config.kind | |
| p = drift_config.payload | |
| if kind == "column_rename": | |
| return _sentence( | |
| "Schema change -", | |
| ( | |
| f"`{p['table']}.{p['old']}` was renamed to `{p['table']}.{p['new']}` " | |
| "as part of a naming normalization. Impact: queries that SELECT, JOIN, " | |
| "GROUP BY, ORDER BY, or filter on the old identifier now fail at bind " | |
| "time. Migration: use the new column everywhere the old one appeared; " | |
| "related table primary keys are unchanged. Validate that counts and " | |
| "aggregates are unchanged after the rename." | |
| ), | |
| ) | |
| if kind == "date_format": | |
| return _sentence( | |
| "Format change -", | |
| ( | |
| f"`{p['table']}.{p['col']}` no longer stores ISO-8601 strings; it now " | |
| "stores BIGINT milliseconds since the Unix epoch. Impact: quoted " | |
| "timestamp literals and text comparisons no longer express the right " | |
| "predicate. Migration: keep the same half-open time window, but compare " | |
| "against numeric epoch-ms bounds. Validate with describe_table and a " | |
| "small sample before submitting." | |
| ), | |
| ) | |
| if kind == "enum_rule": | |
| new_values = ", ".join(f"`{v}`" for v in p["new_values"]) | |
| return _sentence( | |
| "Business-rule change -", | |
| ( | |
| f"`{p['table']}.{p['col']}` value `{p['old_value']}` has been split " | |
| f"into {new_values}. Impact: equality predicates on the old value " | |
| "silently undercount after the deploy. Migration: replace the single " | |
| "value predicate with an IN predicate over every replacement label. " | |
| "Validate by sampling the enum distribution and preserving the existing " | |
| "GROUP BY and projection." | |
| ), | |
| ) | |
| if kind == "field_deprecation": | |
| orig_t, orig_c = p["orig"] | |
| lt, lid, lname = p["lookup"] | |
| fk_col = f"{lt}_{lid}" | |
| return _sentence( | |
| "Deprecation -", | |
| ( | |
| f"`{orig_t}.{orig_c}` was deprecated and replaced by `{orig_t}.{fk_col}` " | |
| f"pointing at `{lt}.{lid}`; the display value now lives on `{lt}.{lname}`. " | |
| "Impact: projections or groups over the old inline string fail after " | |
| "drift. Migration: join through the lookup table, project the display " | |
| "column, and keep the old output alias if callers expect it. Validate " | |
| "row counts after the join." | |
| ), | |
| ) | |
| raise ValueError(f"unknown drift kind={kind!r}") | |
| __all__ = ["author_changelog"] | |