mirror of
https://github.com/multica-ai/multica.git
synced 2026-06-16 19:29:26 +02:00
docs(skills): sync mentioning/squads source maps with shared trigger computation
The squads source map still pointed the comment-trigger contract at the pre-refactor call chain (comment.go:940 -> shouldEnqueueSquadLeaderOnComment), and the mentioning skill referenced the deleted wrapper. Re-anchor both to computeCommentAgentTriggers / computeAssignedSquadLeaderCommentTrigger / computeMentionedAgentCommentTriggers with current line numbers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -57,11 +57,10 @@ match, or the link resolves to the wrong entity (or to nothing).
|
||||
| link a person | `member` | member.user_id | renders a link; enqueues NOTHING — no agent run |
|
||||
| reference an issue | `issue` | issue.id | renders a link; enqueues NOTHING — always safe |
|
||||
|
||||
The enqueue logic lives in `enqueueMentionedAgentTasks`
|
||||
(`server/internal/handler/comment.go`). The actual mention trigger set is
|
||||
computed by `computeMentionedAgentCommentTriggers`, then the comment path
|
||||
passes that result through `computeCommentAgentTriggers` before enqueueing. It
|
||||
acts on two types only: the `squad` branch resolves the squad and adds its
|
||||
The mention trigger set is computed by `computeMentionedAgentCommentTriggers`
|
||||
(`server/internal/handler/comment.go`); the comment path folds that result into
|
||||
`computeCommentAgentTriggers` and enqueues it via `enqueueCommentAgentTriggers`.
|
||||
It acts on two types only: the `squad` branch resolves the squad and adds its
|
||||
leader to the trigger set; everything that is not `agent` after that is skipped
|
||||
(`if m.Type != "agent" { continue }`), then the `agent` branch adds that agent.
|
||||
A `member` or `issue` mention reaches neither branch, so it enqueues no task.
|
||||
|
||||
@@ -30,37 +30,37 @@ a pointer. Branch where verified: `feat/builtin-skills`.
|
||||
|
||||
| Fact | Source |
|
||||
| --- | --- |
|
||||
| `computeCommentAgentTriggers` is the shared comment trigger computation used before enqueueing | `server/internal/handler/comment.go:1101-1133` |
|
||||
| `enqueueMentionedAgentTasks` now delegates to the mention trigger computation and shared enqueue helper | `server/internal/handler/comment.go:1308-1310` |
|
||||
| It is called for comment creation via `triggerTasksForComment`, which computes triggers, applies suppressions, then enqueues | `server/internal/handler/comment.go:1037-1040` |
|
||||
| `squad` branch: resolve squad in workspace, read `LeaderID`, add the leader trigger | `server/internal/handler/comment.go:1330-1369` |
|
||||
| `squad` → shared enqueue helper calls `EnqueueTaskForSquadLeader` | `server/internal/handler/comment.go:1083-1089` |
|
||||
| Everything not `agent` after the squad branch is skipped: `if m.Type != "agent" { continue }` | `server/internal/handler/comment.go:1372-1374` |
|
||||
| `agent` branch: load agent in workspace, then add the agent trigger | `server/internal/handler/comment.go:1375-1402` |
|
||||
| `agent` → shared enqueue helper calls `EnqueueTaskForMention` (a run for that agent) | `server/internal/handler/comment.go:1090-1096` |
|
||||
| **`member` and `issue` mentions reach neither branch — they enqueue NOTHING.** A `member` mention fails the `!= "agent"` skip at lines 1372-1374 (the squad branch above it only matches `squad`); an `issue` mention does the same. | `server/internal/handler/comment.go:1330,1372-1374` |
|
||||
| `computeCommentAgentTriggers` is the shared comment trigger computation used before enqueueing | `server/internal/handler/comment.go:1124-1160` |
|
||||
| `computeMentionedAgentCommentTriggers` builds the mention trigger set; `enqueueCommentAgentTriggers` is the shared enqueue helper | `server/internal/handler/comment.go:1335,1089` |
|
||||
| Comment creation runs `triggerTasksForComment`, which computes triggers, applies suppressions, then enqueues | `server/internal/handler/comment.go:1057-1064` |
|
||||
| `squad` branch: resolve squad in workspace, read `LeaderID`, add the leader trigger | `server/internal/handler/comment.go:1352-1391` |
|
||||
| `squad` → shared enqueue helper calls `EnqueueTaskForSquadLeader` | `server/internal/handler/comment.go:1104-1112` |
|
||||
| Everything not `agent` after the squad branch is skipped: `if m.Type != "agent" { continue }` | `server/internal/handler/comment.go:1394-1396` |
|
||||
| `agent` branch: load agent in workspace, then add the agent trigger | `server/internal/handler/comment.go:1397-1424` |
|
||||
| `agent` → shared enqueue helper calls `EnqueueTaskForMention` (a run for that agent) | `server/internal/handler/comment.go:1113-1119` |
|
||||
| **`member` and `issue` mentions reach neither branch — they enqueue NOTHING.** A `member` mention fails the `!= "agent"` skip at lines 1394-1396 (the squad branch above it only matches `squad`); an `issue` mention does the same. | `server/internal/handler/comment.go:1352,1394-1396` |
|
||||
|
||||
## Preview and suppression
|
||||
|
||||
| Fact | Source |
|
||||
| --- | --- |
|
||||
| Preview route: `POST /api/issues/{id}/comments/trigger-preview` | `server/cmd/server/router.go:667` |
|
||||
| Preview handler loads the issue and parent comment, expands issue identifiers, then calls `computeCommentAgentTriggers` | `server/internal/handler/comment.go:830-874` |
|
||||
| Preview response returns agent `id`, `name`, optional `avatar_url`, `source`, and `reason` | `server/internal/handler/comment.go:781-827` |
|
||||
| `CreateCommentRequest` accepts optional `suppress_agent_ids` | `server/internal/handler/comment.go:768-774` |
|
||||
| `suppress_agent_ids` is parsed as request-boundary UUID input | `server/internal/handler/comment.go:920-927` |
|
||||
| Create comment computes the full trigger set, then applies `filterSuppressedCommentAgentTriggers` before enqueueing | `server/internal/handler/comment.go:1037-1064` |
|
||||
| Preview route: `POST /api/issues/{id}/comments/trigger-preview` | `server/cmd/server/router.go:707` |
|
||||
| Preview handler loads the issue and parent comment, expands issue identifiers, then calls `computeCommentAgentTriggers` | `server/internal/handler/comment.go:832-877` |
|
||||
| Preview response returns agent `id`, `name`, optional `avatar_url`, `source`, and `reason` | `server/internal/handler/comment.go:783-793` |
|
||||
| `CreateCommentRequest` accepts optional `suppress_agent_ids` | `server/internal/handler/comment.go:770-776` |
|
||||
| `suppress_agent_ids` is parsed as request-boundary UUID input | `server/internal/handler/comment.go:925-928` |
|
||||
| Create comment computes the full trigger set, then applies `filterSuppressedCommentAgentTriggers` before enqueueing | `server/internal/handler/comment.go:1057-1087` |
|
||||
|
||||
## Guards that make a valid mention a silent no-op
|
||||
|
||||
| Guard | Source |
|
||||
| --- | --- |
|
||||
| agent archived / no runtime → `continue` (`RuntimeID` invalid or `ArchivedAt` set) | `server/internal/handler/comment.go:1382-1387` |
|
||||
| squad leader archived / no runtime → `continue` | `server/internal/handler/comment.go:1349-1355` |
|
||||
| private agent the actor cannot access → `continue` (`canAccessPrivateAgent`) | `server/internal/handler/comment.go:1389-1392` |
|
||||
| private squad leader the actor cannot trigger → `continue` (`canAccessPrivateAgent`) | `server/internal/handler/comment.go:1357-1360` |
|
||||
| already-pending dedup (agent) → `HasPendingTaskForIssueAndAgent` → `continue` | `server/internal/handler/comment.go:1394-1400` |
|
||||
| already-pending dedup (squad leader) → `continue` | `server/internal/handler/comment.go:1361-1368` |
|
||||
| agent archived / no runtime → `continue` (`RuntimeID` invalid or `ArchivedAt` set) | `server/internal/handler/comment.go:1408-1410` |
|
||||
| squad leader archived / no runtime → `continue` | `server/internal/handler/comment.go:1376-1378` |
|
||||
| private agent the actor cannot access → `continue` (`canAccessPrivateAgent`) | `server/internal/handler/comment.go:1413-1415` |
|
||||
| private squad leader the actor cannot trigger → `continue` (`canAccessPrivateAgent`) | `server/internal/handler/comment.go:1380-1382` |
|
||||
| already-pending dedup (agent) → `HasPendingTaskForIssueAndAgent` → `continue` | `server/internal/handler/comment.go:1417-1423` |
|
||||
| already-pending dedup (squad leader) → `continue` | `server/internal/handler/comment.go:1384-1390` |
|
||||
| `canAccessPrivateAgent` definition | `server/internal/handler/agent_access.go` (search `func (h *Handler) canAccessPrivateAgent`) |
|
||||
| `canEnqueueSquadLeader` (loads leader, delegates to `canAccessPrivateAgent`) | `server/internal/handler/agent_access.go:82-91` |
|
||||
|
||||
@@ -68,10 +68,10 @@ a pointer. Branch where verified: `feat/builtin-skills`.
|
||||
|
||||
| Fact | Source |
|
||||
| --- | --- |
|
||||
| `commentMentionsOthersButNotAssignee` — decides whether to suppress the assignee's on-comment trigger | `server/internal/handler/comment.go:1179` |
|
||||
| `@all` is treated as a broadcast → returns true → assignee auto-trigger suppressed | `server/internal/handler/comment.go:1191-1194` |
|
||||
| Comment-flow computation that consults it | `server/internal/handler/comment.go:1113-1115` |
|
||||
| `@all` never enqueues a specific agent: it is neither `squad` nor `agent`, so it is skipped in the mention trigger computation | `server/internal/handler/comment.go:1372-1374` |
|
||||
| `commentMentionsOthersButNotAssignee` — decides whether to suppress the assignee's on-comment trigger | `server/internal/handler/comment.go:1206` |
|
||||
| `@all` is treated as a broadcast → returns true → assignee auto-trigger suppressed | `server/internal/handler/comment.go:1217-1221` |
|
||||
| Comment-flow computation that consults it | `server/internal/handler/comment.go:1140-1142` |
|
||||
| `@all` never enqueues a specific agent: it is neither `squad` nor `agent`, so it is skipped in the mention trigger computation | `server/internal/handler/comment.go:1394-1396` |
|
||||
|
||||
## CLI id sources (where the UUID comes from)
|
||||
|
||||
@@ -87,9 +87,9 @@ a pointer. Branch where verified: `feat/builtin-skills`.
|
||||
|
||||
The skill deliberately does **not** assert that a `member` mention "sends a
|
||||
notification." `server/internal/handler/comment.go` has no notification
|
||||
delivery path for member (or issue) mentions: `enqueueMentionedAgentTasks`
|
||||
delivery path for member (or issue) mentions: `computeMentionedAgentCommentTriggers`
|
||||
branches only on `squad` and `agent`
|
||||
(`server/internal/handler/comment.go:1330,1372-1374`), and a grep of the file for
|
||||
(`server/internal/handler/comment.go:1352,1394-1396`), and a grep of the file for
|
||||
`notif` returns only an unrelated comment about avoiding "log spam" on
|
||||
unchanged threads — no member-notification call. The verified contract is
|
||||
narrow: a `member` or `issue` mention renders as a link and enqueues no agent
|
||||
|
||||
@@ -121,23 +121,26 @@ Contracts:
|
||||
Source:
|
||||
|
||||
```text
|
||||
server/internal/handler/comment.go # comment-trigger ~940-941, squad mention ~1089
|
||||
server/internal/handler/squad.go # shouldEnqueueSquadLeaderOnComment ~909, enqueueSquadLeaderTask ~1027
|
||||
server/internal/handler/comment.go # comment triggers ~1057-1199, squad mention branch ~1352
|
||||
server/internal/handler/squad.go # enqueueSquadLeaderTask ~986 (assign/backlog paths), lastTaskWasLeader ~915
|
||||
server/internal/service/task.go # EnqueueTaskForSquadLeader
|
||||
```
|
||||
|
||||
Contracts:
|
||||
|
||||
- commenting on a squad-assigned issue can wake the leader
|
||||
(comment.go:940-941 → shouldEnqueueSquadLeaderOnComment at squad.go:909);
|
||||
- explicit `mention://squad/<id>` resolves squad and enqueues leader
|
||||
(comment.go:1089);
|
||||
- commenting on a squad-assigned issue can wake the leader — the comment path
|
||||
computes triggers via `computeCommentAgentTriggers` (comment.go:1124), whose
|
||||
assigned-squad branch is `computeAssignedSquadLeaderCommentTrigger`
|
||||
(comment.go:1162-1199); the same computation backs the trigger-preview
|
||||
endpoint;
|
||||
- explicit `mention://squad/<id>` resolves squad and adds the leader trigger
|
||||
(comment.go:1352-1391);
|
||||
- squad mention does not fan out to members — enqueue targets `squad.LeaderID`
|
||||
only (squad.go:1050);
|
||||
only (comment.go:1104-1112, and squad.go:1007 on the assign/backlog paths);
|
||||
- leader task uses `is_leader_task=true` (via `EnqueueTaskForSquadLeader`);
|
||||
- leader self-trigger loops are guarded — same-leader / last-task-was-leader
|
||||
guards (squad.go:929-932, lastTaskWasLeader at squad.go:959) and member
|
||||
explicit-mention skip (squad.go:939-941).
|
||||
guards (comment.go:1173-1176, lastTaskWasLeader at squad.go:915) and member
|
||||
explicit-mention skip (comment.go:1177-1179).
|
||||
|
||||
## Autopilot
|
||||
|
||||
|
||||
Reference in New Issue
Block a user