fix(photo-loader): HELD batch barrier so create_batch no longer auto-sends via cron#1190
Merged
axisrow merged 3 commits intoJun 28, 2026
Conversation
…sends via cron (#1173) Introduces PhotoBatchStatus.HELD: create_batch now stores the batch and its items as HELD, which claim_next_due_item (cron photo_due) ignores. A new explicit publish_batch verb moves HELD items into the PENDING queue so only run_photo_due / cron can send them afterwards. Owner decision (#1173): posting via cron is a defect — 'create a batch' must not mean 'create and send'. Deferred delivery already has native Telegram scheduling (schedule_send -> SCHEDULED), so HELD is a distinct pre-publish barrier, not a reuse of SCHEDULED. Surfaces (CLI/Web/Agent parity): - Web: POST /dialogs/photos/batches/{id}/publish + dashboard button - CLI: photo-loader publish BATCH_ID - Agent: publish_photo_batch tool with confirmation gate Also: cancel_item now accepts HELD, _sync_batch_status surfaces HELD, jobs_read_model maps HELD, tool_permissions_snapshot + parity docs updated. Closes #1173
… edge-case test (#1190 review) Dual-review fixups for PR #1190: 1. BLOCKER: add ('photo-loader','publish') to CLI_REAL_TG_MANUAL_OR_EXCLUDED_COMMANDS — the CLI leaf-coverage test (test_real_telegram_policy.py::test_cli_real_tg_parser_leaf_commands...) failed CI because the new local-only command was not manifested. 2. MED: wrap publish_batch in a single transaction() so the items-flip and the batch-status update are atomic. Without this the photo_due cron could claim a just-published item between the two writes, _sync_batch_status would flip the batch to RUNNING, and the second write would clobber it back to PENDING. 3. LOW: add test_missing_batch_id_returns_error for publish_photo_batch agent tool (batch_id is None path).
…gh (#1190) Adding PhotoLoaderBundle.publish_batch (a one-line repo delegation) raised the bundle method count from 135 to 136. Update the convention baseline accordingly.
axisrow
added a commit
that referenced
this pull request
Jun 28, 2026
- Stub bundle.count_due_items in TestPhotoTaskServiceRunDue (4 tests) — run_due now calls it unconditionally; bare MagicMock bundles raised "MagicMock can't be used in 'await'" (signature-change-breaks-fakes, #1117). - run_due item_id path: on_progress(1, max(due_total, 1)) avoids "[1/0]" when an item is claimed by id before its schedule_at; loop path caps total at processed so progress never exceeds the snapshot total. - Merge resolution kept the #1190 HELD Publish button: photo_loader_batch_row.html now carries the publish-form column (HELD batches stay web-publishable) and the table header has the Прогресс + publish columns. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TShpckA1DoLNezbD3txTL1
axisrow
added a commit
that referenced
this pull request
Jun 29, 2026
…-count) (#1194) * feat(photo-loader): progress bar for batch scheduling (CLI + web item-count) CLI: optional on_progress callback in PhotoTaskService.run_due and PhotoAutoUploadService.run_due; run_due_impl prints plain "[done/total] ... (~Xm left)" per item plus a final summary. No new dependencies (extends the existing print(f"[N]...") pattern). Without a callback (None) behaviour is unchanged — existing test fakes keep working. Web (item-count parity): new repo count method (completed/total items per batch), surfaced via jobs_read_model; new HTMX fragment photo_loader_batch_row.html with hx-get/hx-trigger="every 5s" polling on RUNNING batches (server-driven swap, per the HTMX policy — not fetch/SSE). Tests: CLI progress callback, repo counts, jobs_read_model fields, route fragment, photo task lifecycle. 99 passed isolated; ruff clean. Closes #1152 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TShpckA1DoLNezbD3txTL1 * fix(photo-loader): review fixups for #1152 progress bar - Stub bundle.count_due_items in TestPhotoTaskServiceRunDue (4 tests) — run_due now calls it unconditionally; bare MagicMock bundles raised "MagicMock can't be used in 'await'" (signature-change-breaks-fakes, #1117). - run_due item_id path: on_progress(1, max(due_total, 1)) avoids "[1/0]" when an item is claimed by id before its schedule_at; loop path caps total at processed so progress never exceeds the snapshot total. - Merge resolution kept the #1190 HELD Publish button: photo_loader_batch_row.html now carries the publish-form column (HELD batches stay web-publishable) and the table header has the Прогресс + publish columns. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TShpckA1DoLNezbD3txTL1 * test(db): bump bundle method baseline 136→138 for #1152 count helpers count_due_items / count_items_by_batch_status are consumed by PhotoTaskService / JobsReadModel (which hold a PhotoLoaderBundle, not db.repos), so the progress-count reads must live on the bundle surface. Legitimate +2 growth — raise the ratchet cap accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TShpckA1DoLNezbD3txTL1 --------- Co-authored-by: axisrow <axisrow@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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
create_batchno longer drops items into the cron-visiblePENDINGqueue. A newPhotoBatchStatus.HELDstate holds them back until an explicitpublish_batchmoves them intoPENDING, so thephoto_duecron job cannot send a freshly-created batch without a deliberate publish step.Closes #1173
Owner decision (semantic)
HELD is a distinct pre-publish barrier, not a reuse of SCHEDULED (SCHEDULED = already queued server-side on Telegram via schedule_send). The cron job claim_next_due_item only claims PENDING, so HELD items are invisible to it.
Root cause (before)
Fix
Core barrier:
Consistency:
Surfaces (CLI / Web / Agent parity)
Parity docs updated: docs/reference/parity.md, docs/reference/agent-tools.md, docs/reference/cli.md, docs/feature-map.md.
Tests (RED to GREEN)
Verification