fix(sync): make outer consecutive-fix breaker progress-sensitive (refs #1203) - #1245
Conversation
gltanaka
left a comment
There was a problem hiding this comment.
Do not merge as-is. The parent issue is real, and a progress-sensitive outer sync fix may still be useful, but this PR needs changes before merge.
Required changes:
-
Pass the resolved path hints into the new progress check. The new
pdd/sync_orchestration.pycall usesread_run_report(basename, language)withoutpaths=pdd_files, while the surrounding sync code now consistently passespaths=pdd_filesfor issue #1211. In a parent-CWD/subproject setup, the pathless call reads the wrong.pdd/metaand returnsNone, so the new failure history records0instead of the actual failing-test count. That can make the progress-sensitive breaker behave incorrectly exactly in the subproject workflow we recently fixed. Required fix: useread_run_report(basename, language, paths=pdd_files)and add a regression where the run report is under a subproject.pdd/metawhile sync is invoked from the parent directory. -
Reconcile this PR with the narrower open PRs for the split work (#1233 and #1235). This PR overlaps #1235's prompt guidance, but with a broader absolute "NEVER exact-string" rule and without the same context/docs updates or carve-outs for contractual/structured message text. Either remove the prompt-template changes from this PR and let #1235 carry that work, or rebase and align the wording/docs so we do not merge duplicate or conflicting prompt guidance.
-
Document or remove the new hard caps. The code adds a hard 30-operation limit and a hard 15-minute wall-clock limit, but
sync_orchestration_python.promptonly documents the consecutive-fix breaker change. If these caps are intentional, they need to be part of the prompt contract and should be justified/tested as user-visible sync behavior; otherwise they should be left out of this fix.
I would not merge #1245 until these are addressed.
96d53de to
7220a3e
Compare
PDD-Auto-Heal-Checkpoint: success
|
Reframed and rescoped this per your review. It's no longer trying to resolve #1203 — #1230 (inner loop) and #1231 (#1235, prompts) already cover the parent via #1300. This PR now does one thing: hardens the outer consecutive-fix breaker in The gap: a single outer Addressing your three points:
Changed the closing keyword to |
gltanaka
left a comment
There was a problem hiding this comment.
Still do not merge as-is. The substantive direction is now much cleaner, and the earlier blockers are mostly addressed: the path-aware read_run_report(..., paths=pdd_files) fix is present, #1233/#1235 are merged, the prompt-template overlap was removed, and the hard caps were removed.
Required changes before merge:
-
Update the source prompt contract.
pdd/sync_orchestration.pynow implements a progress-sensitive outer consecutive-fix breaker, butpdd/prompts/sync_orchestration_python.promptstill saysConsecutive fix operations: Break after 5. In this prompt-driven repo, that leaves the generated module behavior out of sync with its source prompt and risks a futurepdd sync sync_orchestrationregenerating the old progress-blind breaker. Add the progress-sensitive rule to the prompt contract, including thepaths=pdd_filesrun-report lookup requirement for #1211. -
Fix the whitespace / generated artifact churn.
git diff --check origin/main...origin/pr/1245currently fails on trailing whitespace incontext/sync_orchestration_example.pylines 34, 37, 40, 47, 49, 53, 69, and 74. Also please review whether the.pdd/meta/sync_orchestration_python.jsonreset to null hashes and deletion of.pdd/meta/sync_orchestration_python_run.jsonare intentional; those changes look like auto-heal artifact churn rather than part of the fix.
Verification I ran locally in a clean merge worktree:
conda run -n pdd pytest tests/test_issue_1203_breaker.py -q-> 4 passedconda run -n pdd pytest tests/test_sync_orchestration.py::test_budget_exceeded tests/test_sync_orchestration.py::test_dry_run_mode -q-> 2 passedpython -m compileall -q pdd/sync_orchestration.py tests/test_issue_1203_breaker.py context/sync_orchestration_example.py-> passedgit diff --check origin/main...origin/pr/1245-> failed as above
Once the prompt contract and diff hygiene are fixed, this should be close to mergeable.
|
Addressed the latest review blockers in 7c5ada4. The sync orchestration prompt now documents the progress-sensitive outer consecutive-fix breaker, including the path-aware read_run_report(basename, language, paths=pdd_files) requirement for subproject metadata (#1211). I also removed the generated artifact/example churn from the PR diff; the branch diff against origin/main is now limited to pdd/sync_orchestration.py, pdd/prompts/sync_orchestration_python.prompt, and tests/test_issue_1203_breaker.py, and git diff --check origin/main...HEAD is clean locally. Local validation passed: python -m pytest tests/test_issue_1203_breaker.py -q; python -m pytest tests/test_sync_orchestration.py::test_budget_exceeded tests/test_sync_orchestration.py::test_dry_run_mode -q; python -m compileall -q pdd/sync_orchestration.py tests/test_issue_1203_breaker.py context/sync_orchestration_example.py. |
# Conflicts: # pdd/prompts/sync_orchestration_python.prompt
gltanaka
left a comment
There was a problem hiding this comment.
Looks good to merge from code review.
The previous blockers are addressed:
sync_orchestration_python.promptnow documents the progress-sensitive outer consecutive-fix breaker and the requiredread_run_report(..., paths=pdd_files)lookup.- The generated artifact churn and trailing whitespace are gone; the diff is down to the prompt contract,
sync_orchestration.py, and the focused regression test. - The PR still avoids the earlier prompt-template overlap and hard-cap additions.
Local verification against a clean merge into current origin/main:
conda run -n pdd pytest tests/test_issue_1203_breaker.py -q-> 4 passedconda run -n pdd pytest tests/test_sync_orchestration.py::test_budget_exceeded tests/test_sync_orchestration.py::test_dry_run_mode -q-> 2 passedpython -m compileall -q pdd/sync_orchestration.py tests/test_issue_1203_breaker.py-> passedgit diff --cached --checkin the merge worktree -> passed
GitHub currently marks the branch as behind, but the local merge onto current origin/main applied cleanly.
…ve-fix breaker (#1203) The existing test_progress_sensitive_breaker_condition re-implements the breaker decision inline, so it does not exercise the production code path. Add an integration test that drives the REAL sync_orchestration() loop on a real on-disk project (prompt/code/test/example + a real .pdd/meta run report) with only the LLM-calling leaf operations stubbed. The run report's failing-test count strictly decreases across consecutive fix operations (5->4->3->2->1->0); the real breaker reads it via the real read_run_report(..., paths=...). Asserts the breaker stays open past the cap of 5 and the loop converges to all_synced. Verified this test FAILS on origin/main's unconditional `consecutive_fixes >= 5` breaker with the exact #1203 symptom ("Detected 5 consecutive fix operations. Breaking infinite fix loop.", operations_completed=4 fixes) and PASSES with this PR's progress-sensitive condition — proving the change is necessary at the production-loop level. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Verified necessity against the real
|
gltanaka
left a comment
There was a problem hiding this comment.
Still good to merge after the latest update.
The new real-loop regression test is a useful addition: it exercises the production sync_orchestration() loop and demonstrates the breaker stays open past the old cap while failures strictly decrease.
Local verification against a clean merge onto current origin/main:
conda run -n pdd pytest tests/test_issue_1203_breaker.py tests/test_sync_orchestration.py::test_consecutive_fix_breaker_stays_open_while_failures_decrease -q-> 5 passedconda run -n pdd pytest tests/test_sync_orchestration.py::test_budget_exceeded tests/test_sync_orchestration.py::test_dry_run_mode -q-> 2 passedpython -m compileall -q pdd/sync_orchestration.py tests/test_issue_1203_breaker.py tests/test_sync_orchestration.py-> passedgit diff --cached --checkin the merge worktree -> passed
GitHub still reports the branch as behind, but it remains mergeable and the local merge onto current origin/main applied cleanly.
gltanaka
left a comment
There was a problem hiding this comment.
Re-approved after updating the branch from main. The diff remains scoped to the same four files, and is clean locally. Waiting on the fresh required checks before merge.
gltanaka
left a comment
There was a problem hiding this comment.
Re-approved current head after the latest branch update from main. Diff remains unchanged in scope and is clean.
gltanaka
left a comment
There was a problem hiding this comment.
Re-approved current head after branch update. Diff remains scoped to four files and diff check is clean; waiting on fresh required checks before merge.
gltanaka
left a comment
There was a problem hiding this comment.
Re-approved after updating the branch to current main. Revalidated that the refreshed diff is unchanged in scope (same 4 files, 211 insertions/4 deletions) and passes git diff --check. Waiting on the rerun required checks before merge.
Summary
Complements the already-merged inner-loop fix for #1203 by closing a gap one layer up.
#1230 (merged) made the inner
fix_error_loopprogress-sensitive via anassertion/logic stagnation streak. But a single outer
fixoperation runs thatwhole inner loop (
fix_main(..., loop=True, max_attempts=5)). When a fixoperation makes partial progress yet exhausts its inner
max_attemptswithoutfully converging, the sync orchestrator re-selects
fix, and the outerconsecutive-fix breaker in
sync_orchestration.pyis still progress-blind — ittrips at 5 consecutive operations even when the failing-test count is strictly
decreasing across them. This is the exact symptom #1203 reported
("Detected 5 consecutive fix operations").
Refs #1203. Does not close it — the parent is tracked by #1300 (combining
#1230 + #1231). This is a complementary hardening of the outer breaker only.
Changes
pdd/sync_orchestration.py: the consecutive-fix breaker now fires only whenconsecutive_fixes >= MAX_CONSECUTIVE_FIXES(5, now a named constant matchingthe sibling breakers) and the failing-test count did not strictly decrease
versus the prior fix operation. Failure count is read via
read_run_report(basename, language, paths=pdd_files)so the correctsubproject
.pdd/metais honored (pdd fix from a parent dir writes orphan files to run cwd instead of the subproject #1211).tests/test_issue_1203_breaker.py: subproject-meta path-resolution regressionplus parametrized progress/stagnation cases.
Scope notes
budgetguard backstops the outer loop.