Compare commits

...

8 Commits

Author SHA1 Message Date
core-be 0ed272e537 Merge pull request 'merge: merge main into runtime/fix-offsec-003-tool-delegate-task (PR #490 follow-up)' (#514) from merge-pr490 into runtime/fix-offsec-003-tool-delegate-task 2026-05-11 16:45:18 +00:00
core-be 4b3d29d1b5 Merge branch 'origin/main' into merge-pr490
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 3s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 3s
sop-tier-check / tier-check (pull_request) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 4s
audit-force-merge / audit (pull_request) Successful in 3s
Conflict resolved in test_a2a_tools_delegation.py:
- main's TestPollingPathSanitization version used (OFFSEC-003 canonical pattern)
2026-05-11 16:43:17 +00:00
core-lead fc1b15b46a Merge pull request 'fix(workspace): update test_delegation_sync_via_polling assertions for OFFSEC-003 (PR #477)' (#508) from sre/fix-test-delegation-sync-polling-assertions into main
Block internal-flavored paths / Block forbidden paths (push) Successful in 13s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 9s
CI / Detect changes (push) Successful in 25s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 26s
E2E API Smoke Test / detect-changes (push) Successful in 30s
Handlers Postgres Integration / detect-changes (push) Successful in 31s
Runtime PR-Built Compatibility / detect-changes (push) Successful in 29s
CI / Platform (Go) (push) Successful in 6s
CI / Shellcheck (E2E scripts) (push) Successful in 5s
CI / Canvas (Next.js) (push) Successful in 8s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 8s
CI / Canvas Deploy Reminder (push) Has been skipped
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 6s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 7s
publish-runtime-autobump / autobump-and-tag (push) Failing after 47s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (push) Successful in 1m48s
CI / Python Lint & Test (push) Failing after 6m27s
Sweep stale Cloudflare Tunnels / Sweep CF tunnels (push) Failing after 4s
Sweep stale e2e-* orgs (staging) / Sweep e2e orgs (push) Successful in 7s
Staging SaaS smoke (every 30 min) / Staging SaaS smoke (push) Failing after 4m27s
main-red-watchdog / watchdog (push) Successful in 40s
Continuous synthetic E2E (staging) / Synthetic E2E against staging (push) Failing after 4m55s
2026-05-11 16:37:38 +00:00
infra-sre ec20cd04ba fix(workspace): update 3 test assertions for OFFSEC-003 boundary wrapping (PR #477)
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 10s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 14s
sop-tier-check / tier-check (pull_request) Successful in 16s
CI / Detect changes (pull_request) Successful in 36s
E2E API Smoke Test / detect-changes (pull_request) Successful in 40s
CI / Platform (Go) (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 44s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 44s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 8s
CI / Canvas (Next.js) (pull_request) Successful in 9s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 46s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 8s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 8s
audit-force-merge / audit (pull_request) Successful in 15s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 2m13s
CI / Python Lint & Test (pull_request) Failing after 6m44s
PR #477 added _A2A_BOUNDARY_START/END wrapping to tool_delegate_task's
success path. Three tests in test_delegation_sync_via_polling.py were
still asserting exact raw strings and broke:

  test_flag_off_uses_send_a2a_message_not_polling
  test_queued_sentinel_triggers_polling_fallback
  test_non_queued_send_result_does_not_trigger_fallback

Fix: check for boundary markers + inner content instead of exact match.
Import _A2A_BOUNDARY_START/END from _sanitize_a2a in the affected
test methods.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 16:29:31 +00:00
core-devops c9dfb70314 Merge pull request 'chore(workspace): remove unused imports and f-string prefixes' (#506) from ci/lint-fixes into main
Block internal-flavored paths / Block forbidden paths (push) Successful in 6s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 12s
CI / Detect changes (push) Successful in 25s
CI / Platform (Go) (push) Successful in 7s
CI / Shellcheck (E2E scripts) (push) Successful in 6s
E2E API Smoke Test / detect-changes (push) Successful in 41s
CI / Canvas (Next.js) (push) Successful in 10s
CI / Canvas Deploy Reminder (push) Has been skipped
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 8s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 54s
Runtime PR-Built Compatibility / detect-changes (push) Successful in 54s
Handlers Postgres Integration / detect-changes (push) Successful in 59s
publish-runtime-autobump / autobump-and-tag (push) Failing after 1m4s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 7s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 5s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (push) Successful in 2m13s
Sweep stale Cloudflare DNS records / Sweep CF orphans (push) Failing after 22s
ci-required-drift / drift (push) Failing after 51s
CI / Python Lint & Test (push) Failing after 6m54s
Sweep stale e2e-* orgs (staging) / Sweep e2e orgs (push) Successful in 6s
Sweep stale AWS Secrets Manager secrets / Sweep AWS Secrets Manager (push) Failing after 11s
Staging SaaS smoke (every 30 min) / Staging SaaS smoke (push) Failing after 4m27s
Continuous synthetic E2E (staging) / Synthetic E2E against staging (push) Failing after 4m47s
2026-05-11 16:12:32 +00:00
core-lead 4d4da1c0a2 Merge branch 'main' into runtime/fix-offsec-003-tool-delegate-task
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 6s
sop-tier-check / tier-check (pull_request) Successful in 8s
CI / Detect changes (pull_request) Successful in 10s
E2E API Smoke Test / detect-changes (pull_request) Successful in 12s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 13s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 13s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 13s
CI / Platform (Go) (pull_request) Successful in 3s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
audit-force-merge / audit (pull_request) Successful in 6s
CI / Python Lint & Test (pull_request) Failing after 1m6s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 1m40s
2026-05-11 15:09:11 +00:00
core-devops 8deeca7013 fix(workspace): resolve PR #477 test failures — OFFSEC-003 test updates
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 13s
CI / Detect changes (pull_request) Successful in 31s
E2E API Smoke Test / detect-changes (pull_request) Successful in 30s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 31s
Harness Replays / detect-changes (pull_request) Failing after 12s
Harness Replays / Harness Replays (pull_request) Has been skipped
Handlers Postgres Integration / detect-changes (pull_request) Successful in 36s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 13s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 36s
sop-tier-check / tier-check (pull_request) Successful in 15s
CI / Platform (Go) (pull_request) Successful in 7s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 6s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 8s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 13s
CI / Python Lint & Test (pull_request) Failing after 2m14s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 2m19s
CI / Canvas (Next.js) (pull_request) Failing after 6m28s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 7m28s
1. test_a2a_tools_impl.py: same 3 assertion updates as PR #475 fix —
   OFFSEC-003 (commit 2add6333) wrapped tool_delegate_task results in
   [A2A_RESULT_FROM_PEER] boundary markers. Update
   test_success_returns_result_text, test_peer_name_cached, and
   test_peer_name_fallback to expect wrapped form.

2. Remove TestDelegateTaskDirect class (tests non-existent
   a2a_tools.delegate_task function).

3. test_a2a_tools_delegation.py: add TestPollingPathSanitization class
   with test_completed_response_sanitized. Verifies that results from
   _delegate_sync_via_polling are correctly wrapped by tool_delegate_task
   with [A2A_RESULT_FROM_PEER] boundary markers (OFFSEC-003 trust
   boundary).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 14:45:01 +00:00
infra-runtime-be 0239b5ff72 fix(workspace): OFFSEC-003 — separate sanitize vs. wrap, fix tool_delegate_task
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 9s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 15s
sop-tier-check / tier-check (pull_request) Successful in 17s
E2E API Smoke Test / detect-changes (pull_request) Successful in 28s
CI / Detect changes (pull_request) Successful in 30s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 30s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 30s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 30s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 7s
CI / Platform (Go) (pull_request) Successful in 5s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 6s
CI / Canvas (Next.js) (pull_request) Successful in 7s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 8s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 2m5s
CI / Python Lint & Test (pull_request) Failing after 6m50s
PRs #431 and #469 remove `sanitize_a2a_result(result)` from
`tool_delegate_task` without adding explicit boundary wrapping.
Both the direct send_a2a_message path and the _delegate_sync_via_polling
fallback would return completely unsanitized peer text — a security regression.

Fix:
- `_sanitize_a2a.sanitize_a2a_result()`: remove internal wrapping.
  Separation of concerns makes the escaping contract visible at call sites.
- `a2a_tools_delegation.tool_delegate_task()`: add explicit boundary
  wrapping around the sanitized result.
- `test_a2a_sanitization.py`: rewrite tests for the new contract.
  Wrapping is now tested at the caller level (tool_delegate_task pattern).

The broader OFFSEC-003 improvements in PR #469 (space-substitution,
broadened INSTRUCTIONS pattern, plugin registry sys.modules fix) are
good — this PR ensures the security guarantees hold when those land.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 14:12:05 +00:00
@@ -64,10 +64,12 @@ class TestFlagOffLegacyPath:
async def test_flag_off_uses_send_a2a_message_not_polling(self, monkeypatch):
"""With DELEGATION_SYNC_VIA_INBOX unset, tool_delegate_task must
invoke the legacy send_a2a_message and NEVER call /delegate."""
invoke the legacy send_a2a_message and NEVER call /delegate.
Result is wrapped in _A2A_BOUNDARY_START/END (OFFSEC-003, PR #477)."""
monkeypatch.delenv("DELEGATION_SYNC_VIA_INBOX", raising=False)
import a2a_tools
from _sanitize_a2a import _A2A_BOUNDARY_END, _A2A_BOUNDARY_START
send_calls = []
async def fake_send(workspace_id, task, source_workspace_id=None):
@@ -88,7 +90,10 @@ class TestFlagOffLegacyPath:
"ws-target", "task body", source_workspace_id="ws-self"
)
assert result == "legacy ok", f"expected legacy passthrough, got {result!r}"
# OFFSEC-003: result is wrapped in boundary markers
assert _A2A_BOUNDARY_START in result
assert _A2A_BOUNDARY_END in result
assert "legacy ok" in result
assert send_calls == [("ws-target", "task body", "ws-self")]
poll_mock.assert_not_called()
@@ -119,6 +124,7 @@ class TestPollModeAutoFallback:
monkeypatch.delenv("DELEGATION_SYNC_VIA_INBOX", raising=False)
import a2a_tools
from _sanitize_a2a import _A2A_BOUNDARY_END, _A2A_BOUNDARY_START
from a2a_client import _A2A_QUEUED_PREFIX
send_calls = []
@@ -152,8 +158,10 @@ class TestPollModeAutoFallback:
assert len(poll_calls) == 1
assert poll_calls[0] == ("ws-target", "task body", "ws-self")
# Caller sees the real reply, NOT the queued sentinel and NOT
# a DELEGATION FAILED string.
assert result == "real response from poll-mode peer"
# a DELEGATION FAILED string. Wrapped in OFFSEC-003 boundary markers.
assert _A2A_BOUNDARY_START in result
assert _A2A_BOUNDARY_END in result
assert "real response from poll-mode peer" in result
async def test_non_queued_send_result_does_not_trigger_fallback(self, monkeypatch):
# Push-mode peer returns a normal text reply — fallback path
@@ -161,6 +169,7 @@ class TestPollModeAutoFallback:
monkeypatch.delenv("DELEGATION_SYNC_VIA_INBOX", raising=False)
import a2a_tools
from _sanitize_a2a import _A2A_BOUNDARY_END, _A2A_BOUNDARY_START
async def fake_send(*_a, **_kw):
return "normal reply"
@@ -179,7 +188,10 @@ class TestPollModeAutoFallback:
"ws-target", "task", source_workspace_id="ws-self"
)
assert result == "normal reply"
# OFFSEC-003: wrapped in boundary markers
assert _A2A_BOUNDARY_START in result
assert _A2A_BOUNDARY_END in result
assert "normal reply" in result
poll_mock.assert_not_called()
async def test_error_send_result_does_not_trigger_fallback(self, monkeypatch):