diff --git a/scripts/ci/agent_mention_router.py b/scripts/ci/agent_mention_router.py old mode 100644 new mode 100755 diff --git a/tests/test_agent_mention_complete_payload_binding.py b/tests/test_agent_mention_complete_payload_binding.py index c07025407..5519e44cc 100644 --- a/tests/test_agent_mention_complete_payload_binding.py +++ b/tests/test_agent_mention_complete_payload_binding.py @@ -162,17 +162,6 @@ def test_wrappers_recompute_complete_claim_before_ledger_access() -> None: assert "--arg pr_base_sha \"$PR_BASE_SHA\"" in workflow assert "pr_base_sha: $pr_base_sha" in workflow - assert "github.event.client_payload.trigger_reviews" not in opencode - assert "github.event.client_payload.review_dispatch_limit" not in opencode - assert "github.event.client_payload.enable_auto_merge" not in opencode - assert "github.event.client_payload.update_branches" not in opencode - assert "github.event.client_payload.merge_mode" not in opencode - assert 'TRIGGER_REVIEWS: "true"' in opencode - assert 'REVIEW_DISPATCH_LIMIT: "1"' in opencode - assert 'ENABLE_AUTO_MERGE: "false"' in opencode - assert 'UPDATE_BRANCHES: "false"' in opencode - assert 'MERGE_MODE: "disabled"' in opencode - for field in ( '"trigger_reviews": os.environ["TRIGGER_REVIEWS"] == "true"', '"review_dispatch_limit": os.environ["REVIEW_DISPATCH_LIMIT"]', @@ -193,6 +182,67 @@ def test_wrappers_recompute_complete_claim_before_ledger_access() -> None: assert opencode.count(field) >= 2 +def test_repository_dispatch_payloads_stay_within_github_property_limit() -> None: + """Keep both OpenCode dispatch hops at GitHub's ten-property API boundary.""" + + router = _load_router() + request = router.parse_event(_event()) + assert request is not None + noema_payload = router.noema_payload(request)["client_payload"] + opencode_payload = router.opencode_payload(request)["client_payload"] + + assert len(noema_payload) <= 10 + assert set(opencode_payload) == { + "target_repository", + "pr_number", + "pr_head_sha", + "pr_base_sha", + "base_branch", + "requested_agent", + "agent_invocation_key", + "requested_by", + "source_comment_id", + } + assert len(opencode_payload) <= 10 + + workflow = OPENCODE_WORKFLOW.read_text(encoding="utf-8") + for constant in ( + 'TRIGGER_REVIEWS: "true"', + 'REVIEW_DISPATCH_LIMIT: "1"', + 'ENABLE_AUTO_MERGE: "false"', + 'UPDATE_BRANCHES: "false"', + 'MERGE_MODE: "disabled"', + ): + assert constant in workflow + + forward = workflow.split( + " - name: Forward once to the authoritative review-only scheduler\n", 1 + )[1] + payload_literal = forward.split("client_payload: {\n", 1)[1].split( + "\n }\n }'", 1 + )[0] + forwarded_keys = { + line.strip().split(":", 1)[0] + for line in payload_literal.splitlines() + if ":" in line + } + assert forwarded_keys == { + "target_repository", + "pr_number", + "pr_head_sha", + "pr_base_sha", + "base_branch", + "enable_auto_merge", + "update_branches", + "merge_mode", + "agent_invocation_key", + "source_comment_id", + } + assert len(forwarded_keys) <= 10 + assert "requested_agent:" not in payload_literal + assert "requested_by:" not in payload_literal + + def test_no_pr_specific_writer_workflow_remains() -> None: """Complete binding is implemented in canonical files, never a branch writer.""" diff --git a/tests/test_agent_mention_router.py b/tests/test_agent_mention_router.py index 874a79e4f..2590e0a1c 100644 --- a/tests/test_agent_mention_router.py +++ b/tests/test_agent_mention_router.py @@ -201,7 +201,7 @@ def test_receipt_and_allowlist_helpers() -> None: def test_eligible_agents_and_payloads() -> None: - """Eligibility and event bodies preserve the bounded review contract.""" + """Eligibility and wrapper transport preserve the bounded review contract.""" module = load_module() request = module.parse_event(event("@cwl-noema-review @opencode-agent")) @@ -218,14 +218,31 @@ def test_eligible_agents_and_payloads() -> None: assert noema["event_type"] == "agent-mention-noema" assert noema["client_payload"]["pr_head_sha"] == "a" * 40 assert noema["client_payload"]["pr_base_sha"] == "b" * 40 + opencode = module.opencode_payload(request) assert opencode["event_type"] == "agent-mention-opencode" + assert set(opencode["client_payload"]) == { + "target_repository", + "pr_number", + "pr_head_sha", + "pr_base_sha", + "base_branch", + "requested_agent", + "agent_invocation_key", + "requested_by", + "source_comment_id", + } + assert len(opencode["client_payload"]) == 9 assert opencode["client_payload"]["base_branch"] == "develop" assert opencode["client_payload"]["pr_base_sha"] == "b" * 40 assert "merge_mode" not in opencode["client_payload"] assert "enable_auto_merge" not in opencode["client_payload"] assert "update_branches" not in opencode["client_payload"] claim = module.agent_invocation_claim(request, "opencode-agent") + + claim = module.agent_invocation_claim(request, "opencode-agent") + assert claim["trigger_reviews"] is True + assert claim["review_dispatch_limit"] == "1" assert claim["merge_mode"] == "disabled" assert claim["enable_auto_merge"] is False assert claim["update_branches"] is False @@ -255,6 +272,7 @@ def test_dispatch_uses_central_events_and_acknowledges() -> None: args[0] == "repos/ContextualWisdomLab/.github/dispatches" for args, _ in dispatches ) + assert len(dispatches[1][1]["client_payload"]) == 9 assert target.calls[0][1] == {"content": "eyes"} assert "cwl-agent-mention-receipt:91" in target.calls[1][1]["body"] assert "exact-name Actions artifacts" in target.calls[1][1]["body"]