* fix(server): attribute agent-created issues so downstream A2A mentions keep the originator (MUL-4305)
An agent creating an issue via the ordinary `issue create` path left the new
issue with no origin link, so resolveOriginatorForIssueTask could not recover
the top-of-chain human. Any assignment / squad-leader run derived from that
issue lost the originator, and A2A @-mentions those runs emitted failed the
canInvokeAgent gate against private agents (after MUL-3963).
Fix (mirrors the comment.source_task_id stamp from MUL-4015):
- CreateIssue stamps origin_type='agent_create' + origin_id=<acting task>,
resolved from the SERVER-trusted X-Task-ID (never a client-reported field).
- resolveOriginatorForIssueTask inherits the origin task's originator for
agent_create just like quick_create.
- Align the squad-leader gate originator with the enqueue path via the new
exported OriginatorForIssueTask, so the gate and the persisted task row
agree instead of drifting to an empty originator for agent-triggered assigns.
- Migration 149 adds 'agent_create' to issue_origin_type_check.
- Classify agent_create in analytics to avoid the unknown-origin warning.
Tests: agent_create attribution + gate/enqueue consistency (service), and the
HTTP boundary stamp + security regression (member / forged X-Agent-ID must not
smuggle an agent_create origin).
Co-authored-by: multica-agent <github@multica.ai>
* test(server): add end-to-end regression for agent-created issue originator chain (MUL-4305)
Locks the real product path the layered tests could miss, per PR review:
1. CreateAssignSquad_PrivateWorkerTriggered — human H triggers agent A → A
creates an issue via the ordinary create path AND assigns it to a squad
whose leader is a private agent owned by H → the leader's assignment run
@-mentions a second private agent J (owned by H) → asserts the leader task
carries H and J ends up with a queued task attributed to H. This is the
exact line-failure shape from the issue.
2. UpdateAssignSquad_HandlerGateAdmitsPrivateLeader — agent A creates an
unassigned issue then assigns it to a private-leader squad via UpdateIssue,
exercising the handler enqueueSquadLeaderTask gate (which the create path's
ungated service enqueue does not hit); asserts the leader task is enqueued
carrying H.
Both wire handler create stamp → origin resolution → squad-leader gate →
comment source-task stamp → private-worker invocation gate. Verified they FAIL
against a simulated pre-fix resolver (leader originator empty; private worker /
leader get 0 tasks) and PASS with the fix.
Co-authored-by: multica-agent <github@multica.ai>
---------
Co-authored-by: Eve <eve@multica-ai.local>
Co-authored-by: multica-agent <github@multica.ai>