Background
SemanticLayerService.edit_metric (and the helper edit_metric_with_cascade in _semantic_layer_crud.py) handles a metric rename + constraint cascade in this order:
- DELETE old metric -> POST new metric (with rollback to original on POST failure).
- For each cascaded constraint: DELETE old -> POST new (with rollback on POST failure).
The per-constraint rollback in step 2 is local -- each cascade item rolls back individually. There is no whole-operation rollback if step 1 succeeded but some step 2 items fail. The current envelope reports per-constraint status (updated / failed) so the caller can detect partial failure, but the model is left in a partially-cascaded state.
Problem
If the operator runs kbagent semantic-layer edit metric --new-name X and the metric POST succeeds but one of N cascaded constraints fails to POST after its DELETE, the partial-success envelope tells you which constraints orphaned themselves, but:
- The original metric name is now gone (renamed to X).
- M of N constraints reference X (the new name), N-M reference the missing old name (now orphans).
- Downstream
DIM_METRIC_THRESHOLD joins on CODE_METRIC will be inconsistent.
The current rollback layer (per-item) prevents data loss for that one item, but doesn't restore atomicity across the cascade.
Acceptance criteria
- Define the rollback semantics explicitly (e.g. all-or-nothing two-phase: stage every cascade item to a side store, then commit; or document the current per-item behaviour as the supported contract and let operators handle partial states via re-run +
kbagent semantic-layer validate).
- If we pick atomic: implement the rollback path that re-POSTs ALL cascade items on partial failure (existing rollback helper covers single-item rollback; the trick is the ordering + the operator-visible envelope).
- Update
kbagent semantic-layer edit metric --new-name docs in keboola-expert.md, commands-reference.md, and gotchas.md to reflect the chosen semantics.
Filed from PR #293 review (pre-merge follow-up tracking)
Background
SemanticLayerService.edit_metric(and the helperedit_metric_with_cascadein_semantic_layer_crud.py) handles a metric rename + constraint cascade in this order:The per-constraint rollback in step 2 is local -- each cascade item rolls back individually. There is no whole-operation rollback if step 1 succeeded but some step 2 items fail. The current envelope reports per-constraint status (
updated/failed) so the caller can detect partial failure, but the model is left in a partially-cascaded state.Problem
If the operator runs
kbagent semantic-layer edit metric --new-name Xand the metric POST succeeds but one of N cascaded constraints fails to POST after its DELETE, the partial-success envelope tells you which constraints orphaned themselves, but:DIM_METRIC_THRESHOLDjoins on CODE_METRIC will be inconsistent.The current rollback layer (per-item) prevents data loss for that one item, but doesn't restore atomicity across the cascade.
Acceptance criteria
kbagent semantic-layer validate).kbagent semantic-layer edit metric --new-namedocs inkeboola-expert.md,commands-reference.md, andgotchas.mdto reflect the chosen semantics.Filed from PR #293 review (pre-merge follow-up tracking)