dfdfbf762b
Per plan v9, the master assembles the worker input_payload at attempt-enqueue time so the worker dequeues a ready-to-use payload with no extra Forgejo I/O of its own. This phase ships per-role V1-input builders + a factory matching the scheduler's PrefetchCallback protocol: - build_implementer_input → ImplementerInputV1 shape (head_sha, head_ref, base_branch, active_reviews, pr_comments_since_last_attempt, prior_attempts, diff_summary) - build_reviewer_input → ReviewerInputV1 shape (full_diff, prior_implementer_attempts, implementer_claim, prior_reviews) - build_estimator_input → EstimatorInputV1 shape (pr_title, pr_body, diff_summary) — works for both PR and issue kinds - build_conflict_resolver_input → ConflictResolverInputV1 shape with conflicted_files=[] stub (worker patches via git rebase) - make_prefetch_callback(engine, callbacks) → routes by role; returns (payload, "V1") matching the scheduler's PrefetchCallback signature Forgejo HTTP wiring adds four new callbacks (get_pr_details, get_pr_diff, list_pr_reviews, list_pr_comments) plumbed through ForgejoCallbacks. Worker-side patches (post-dequeue, pre-validation): - attempt_id, attempt_number (known from dequeue) - workspace_dir (worker filesystem path) - wallclock_budget_s (worker config) What this phase DOES NOT yet produce: - ci_summary / failing_gates — Phase 1j (deterministic CI summarizer) - Issue-kind estimator's title/body — needs list_issue_details callback (defer to future phase) - conflict_resolver's actual conflicted_files — needs worker-side git rebase + conflict-parse pass Tests (+26 in test_master_prefetch.py, 0 regressions): - Per-role shape validation + V1 contract parse after worker patches - Prior-attempts merge (verbatim cap=3, oldest-first, total count) - Active-reviews projection (filters invalid states/missing user) - pr_comments_since_last_attempt filtering by finished_at - Factory routes by role; unknown role raises - Scheduler integration end-to-end (real prefetch → real INSERT) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>