Live race seen 2026-05-06: bookcheck teardown committed at T (removed
the slug from tenants/kustomization.yaml + pruned its directory).
Multitest provision's first commit attempt at T-2s got a ref-race
rejection, the github client's retry replayed the SAME files map (which
held the pre-teardown parent kustomization with bookcheck still in it),
and the retry's commit at T+5s overwrote the teardown's removal. Result:
the parent kustomization listed bookcheck but the directory was gone,
Flux's tenants Kustomization wedged in build-failure loop, and EVERY
subsequent tenant change was blocked until manually unblocked.
Add CommitFilesWithPruneAndRebuild — same as CommitFilesWithPrune but
takes a `rebuild(ctx) (files, error)` callback invoked at the start of
each attempt. Wire both consumer paths (provision + teardown) through
it; each rebuild re-reads parent kustomization.yaml against the current
HEAD and re-applies UpdateParentKustomization / RemoveTenantFromParentKustomization
fresh. Static tenant-scoped manifests still flow through unchanged.
CommitFilesWithPrune is preserved as a thin wrapper for callers that
ship truly static files (e.g. day-2 app installs scoped to a tenant
subdir, no parent merge involved).
Co-authored-by: hatiyildiz <hatice@openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>