Commit Graph

7 Commits

Author SHA1 Message Date
m-senior-developer 11d1d675dd WYL-51 round 2: requirement anchoring retrigger comment
Replace the round-1 summariser approach with the full anchor pattern:

A. _post_rejection_retrigger(round_, client, issue, verdict_comment_content, logger)
   - Renamed from _notify_assignee_on_reject
   - Non-agent/no-assignee path: post a non-mentioning coordinator note and return
   - Agent path: build full anchor comment via _build_retrigger_comment

B. Anchor comment structure (verbatim, no summarising):
   1. [@AssigneeName](mention://agent/<id>)
   2. Verdict: REJECT (round <id>)
   3. ## ANCHOR — Original requirements + full issue description in blockquote
   4. ## Why this was rejected + full judge verdict in blockquote
   5. ## Instructions for rework + REWORK_INSTRUCTIONS constant (verbatim)
   6. Trailing audit line

C. Round.retrigger_comment_id + DebateQueue.set_retrigger_comment_id

D. 8 required tests (D1–D8): mention, verbatim description, no-drift constant,
   member skip, no-assignee skip, accept no-op, id persistence, race regression

E. test_retrigger_on_reject_end_to_end integration test

Removed: _extract_rejection_reasons, _build_rejection_followup (summarisers)
Added: REWORK_INSTRUCTIONS constant, MulticaClient.get_agent_name

Unit: 63 passed. Integration: 1 passed.
2026-04-15 22:24:39 +00:00
m-senior-developer cb6156a4a1 WYL-51: re-trigger assignee on REJECT verdict
After _advance_awaiting_judge kicks an issue back to in_progress on a
REJECT, post a short followup comment that @-mentions the agent assignee
with the verdict, top 2-3 failure reasons, and a retry prompt.

Corner cases handled:
- assignee_type != 'agent' (member or unset) → skip silently
- ACCEPT branch → no notification
- notification failure → logged, round still completes (non-blocking)

New helpers: _extract_rejection_reasons, _build_rejection_followup,
_notify_assignee_on_reject.

+12 tests (5 for _extract_rejection_reasons, 7 for the notify path).
Total: 66 passed.
2026-04-15 22:13:34 +00:00
m-senior-developer 0e44846032 Implement debate round orchestration (WYL-45)
New module: src/coordinator/orchestrator.py
- DEBATER_NAMES, JUDGE_NAME, DEBATER_PROMPTS, JUDGE_PROMPT_TEMPLATE hardcoded for v1
- Per-debater prompts tell each debater exactly which tool output to ground evidence in
- orchestrate_pending() is the main entry point called from watch_loop
- _start_round(): pending→running, posts debater mention comment, phase→awaiting_debaters
- _advance_awaiting_debaters(): polls for replies, handles timeout with partial evidence,
  posts judge comment, phase→awaiting_judge
- _advance_awaiting_judge(): polls for verdict; RACE FIX — update_issue_status() called
  BEFORE queue.update_status("done") so poll_once can never double-enqueue
- Detection: primary=author_id match, fallback=[{name} response]: content marker (enables tests)
- Restart-safe: phase field persisted on every mutation; in-flight rounds resume correctly

Extended src/coordinator/queue.py:
- Round gains phase, phase_entered_at, coordinator_comment_id, judge_comment_id fields
- DebateQueue.update_phase() and running() added
- All new fields default-empty so existing queue.json files load cleanly

Extended src/coordinator/multica_client.py:
- update_issue_status() convenience wrapper
- create_issue() for integration / smoke tests

Updated src/coordinator/__main__.py:
- _orchestrate_pending stub replaced with real import from orchestrator

Tests:
- tests/test_orchestrator.py: 32 new unit tests covering phase transitions, timeouts,
  race fix ordering, restart resume, full lifecycle
- tests/test_integration.py: @pytest.mark.integration test against real API
- smoke_test.py: standalone end-to-end script; ran against real API, verdict OK

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:43:17 +00:00
m-senior-developer 8c9a174ddc WYL-44 follow-up: add tests and extract poll_once for testability
R1: Add unit tests (22 total, all passing)
- tests/test_queue.py: enqueue/persist, is_issue_pending_or_running for all
  statuses, update_status mutate+persist, save/load roundtrip, corrupt file
  handling, pending() filtering
- tests/test_watcher.py: FakeMulticaClient drives poll_once across first
  observation, same updated_at dedupe, updated_at change while pending/running
  dedupe, re-enqueue after done, multi-issue, mix of new and seen

Refactor: extract poll_once(client, state, queue, logger) from watch_loop so
tests can call it directly without mocking time.sleep.

R2: Document known race near is_issue_pending_or_running — comment added
noting that orchestrator marking round done before updating issue status can
fire a second round; WYL-45 must resolve atomically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:20:23 +00:00
m-senior-developer 6ebd36bccc WYL-44: implement in_review watcher with persistent debate queue
- Add queue.py: DebateQueue backed by ~/.coordinator/queue.json
  (Round dataclass, enqueue/update_status/pending/is_issue_pending_or_running)
- Update watch_loop to call queue.enqueue() on in_review transitions instead
  of only logging; skip issues already pending/running to avoid double-queuing
- Add queue_file path to Config
- Add _orchestrate_pending stub (WYL-45 hook point)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:13:53 +00:00
m-platform-admin 6da434039c WYL-42: Python skeleton + in_review watcher loop
Minimum viable structure for the Tool-MAD coordinator:
- coordinator.config: env-loaded Config dataclass, writes state to ~/.coordinator/
- coordinator.multica_client: thin requests wrapper for issues/comments/agents
- coordinator.state: flat-json SeenState tracking issue_id -> last_seen_updated_at
- coordinator.__main__: watch_loop() that polls in_review and logs candidates
- README.md: why this exists + how to run

v0 only detects in_review transitions; convening debate rounds is WYL-45.
Dependencies: stdlib + requests (nothing else until a working v1 ships).
2026-04-15 23:04:06 +02:00
m-platform-admin 3935102d96 Initial commit 2026-04-15 23:00:55 +02:00