fix(sync): push deletes only with --force and skips remote-deleted configs (#792 G, H) - #811
Merged
Merged
Conversation
keboola-pr-reviewer-bot
left a comment
There was a problem hiding this comment.
Verdict: needs_human (risk 3/5) · profile keboola-mcp-server
Well-tested sync-push safety fix, but a silent behavior change with downstream CI impact and a stated merge-order dependency warrant a human sign-off.
Concerns:
plugins/kbagent/skills/kbagent-cicd-migration/SKILL.md: Silent behavior change: plain push stops deleting; pre-existing CI relying on delete-without-force breaks.src/keboola_agent_cli/services/sync_service.py: Declared merge-order dependency (#795/#796) and LOC-cap freeze unverifiable against main.plugins/kbagent/skills/kbagent-promotion-pipeline/scripts/generate_promotion_pipeline.py: Pipelines generated before this need manual --force or source deletions no longer propagate.
zajca
requested changes
Sep 29, 2026
zajca
left a comment
Member
There was a problem hiding this comment.
Actionable findings from the automated review.
…does not re-create it (#792 H)
This was referenced Sep 30, 2026
Merged
zajca
approved these changes
Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was wrong
sync pushdeleted a remote config or row as soon as its local files were missing, also without--force. The--forcehelp says that--forceallows this deletion. Commit 8859949 removed the check and did not change the help.What changed
--force, push deletes nothing on the remote, configs and rows alike. It lists each held-back deletion underskipped_deletionswithskipped_deletions_reason, also for--dry-run. In--dry-run,summary.deletedcounts only the deletions that push applies. The human output names each deletion and the fix.sync diffreports a config or row asremote_deletedwhen the manifest fetched it from the target branch (it has apull_hash) and it is missing on the remote. The human output shows- REMOTE DELETED, and the summary hasremote_deleted. A local row under such a config isremote_deletedtoo. Push does not apply these changes and reports them underskippedwithskipped_reason. These two keys are now in every push result, not only when the status isno_changes.main/into a dev branch, a placeholder entry written by hand, and async clonecopy.sync clonenow drops thepull_hashthat the copied entries carry from the source project.kbagent-promotion-pipelineworkflows now pass--forceto the validate dry-run and to the push, because the pipeline promises that a deletion in the source reaches the destination.commands/_sync_push_render.py, becausecommands/sync.pyis at its size limit.Behavior changes
These changes are intended. The old behavior contradicted the
--forcehelp, and push could delete or create again a remote config without notice. kbagent usage telemetry from 2026-09-20 to 2026-09-29 shows nosync pushfrom a GitHub-hosted runner.--force. Thekbagent-cicd-migrationworkflow already passes--forceonly when itsallow_deleteinput is set. Before this change, push deleted also whenallow_deletewas off.--forcein its validate and push steps.sync diffandsync push --dry-runcan return the new change typeremote_deleted.sync diffmarks deletions as "to delete (push --force)".Tests
tests/test_sync_formal_counterexamples.pyare ordinary regression tests now (noxfail).--dry-runwith and without--force, row deletions without--force, a locally edited config deleted on the remote, rows of a deleted config (a new local row included),--forcewithremote_deletedchanges, the rules in the diff engine and inscope_manifest, the promotion pipeline flags and the human output.xfail(strict=True)).make checkpasses.Merge order
This PR needs #796 and #795 on
mainfirst.services/sync_service.pyis frozen at 1655 code lines. Onmainalone this change is over that limit, and #796 and #795 make it smaller. The branch was tested onmainwith #796, #795, #794 and #810 merged.Docs:
gotchas.md(since vNEXT),sync-workflow.md,sync-rows-workflow.md,commands-reference.md,keboola-expert.md, thekbagent-cicd-migrationandkbagent-promotion-pipelineskills,context.py,CLAUDE.mdandformal/sync/README.md. No version bump, no changelog entry.Refs #792