0b657cd0d9
Post-commit review of d386ff4e surfaced two real bugs and several
rough edges. None changed the architecture — all changes harden the
existing dispatcher↔worker filesystem-handshake contract.
P0 bug fixes
- Three-case read contract for implementer_pr_context.py. The old
``or None`` projection conflated "field missing" with "field
present but empty," forcing the worker to re-curl Forgejo every
time the dispatcher had already confirmed a section was empty.
New contract: empty stdout = "didn't try; fall through to legacy
GET"; ``null\n`` = "tried and authoritatively empty; SKIP GET";
any other content = use it.
- ``comments`` field dispatches on ``work_type`` instead of using
the ``pr_comments or issue_comments`` chain. The old code would
silently leak ``issue_comments`` from a stale issue context into
a ``pr_fix`` worker's ``--field comments`` read.
- Every section's projection now honours its ``*_completed`` flag.
A failed upstream fetch (transient API error) maps to empty
stdout instead of authoritative empty data.
P1 hardening
- Dropped ``_resolve_branch_for_sha``. The pre-clone path was
shelling out to ``git for-each-ref --points-at <sha>`` for data
the dispatcher already had from ``pr_details.head.ref``. Now
``prepare_pr_worktree`` takes ``head_ref`` as a kwarg.
- Both writers (PR-context and workspace sentinels) clean up
their ``.tmp`` orphan files on partial-write / serialisation
failure.
- Removed the dead ``cleanup`` subcommand from
tools/implementer_workspace.py — worktree cleanup is the
dispatcher's job (WorktreeHandle.cleanup); the worker has no
legitimate reason to rm -rf a worktree mid-session.
- Tightened bash allow-rules in task-implementor.md from
``<script> *`` to ``<script> <subcommand> *`` so future
subcommands require explicit operator review.
- Retired the prompt-vs-sentinel "use either" softener in
task-implementor.md and the implementer-pr-context SKILL.md.
The scripts are now documented as the SINGLE SOURCE OF TRUTH.
Test additions
- 5 new dispatcher↔sentinel integration tests in
test_dispatch_implementer.py: writer call site, new_issue
work_type mapping, cleanup integration with and without a
context dict, partial-fetch completion-flag propagation.
- 5 new contract tests in test_implementer_pr_context_cli.py:
the three-case epic contract, work_type dispatch in both
directions, failed-fetch fall-through.
- 2 new sentinel writer tests in test_pr_context_sentinel.py:
``.tmp`` orphan cleanup paths, real ImplementerPrefetchResult
round-trip (defends against silent-attribute-miss when fields
are added to the dataclass).
- ``test_workspace_handoff.py`` integration test now asserts NO
``git for-each-ref`` invocation (regression guard for the
dropped helper).
Full auto_agents suite: 1,128 passed, 3 skipped (was 1,123 before).
Co-authored-by: Cursor <cursoragent@cursor.com>