multica-mentioning について
Multicaでのコメント内メンションの解析方法、エージェントの実行を起動する対象、プレビューや結果の扱いを説明するスキルです。
主な機能
- 01UUIDを使うメンション構文
- 02エージェントとスクワッドの起動規則
- 03メンバーと課題のリンク動作
- 04起動プレビューと抑制
- 05ブロードキャストと保留タスクの規則
活用シーン
- 01コメントからエージェントやスクワッドに依頼
- 02実行を起動せずメンバーや課題をリンク
- 03コメントで起動するエージェントを確認
- 04ブロックまたは統合されたメンションを調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ multica-ai/ multica --skill multica-mentioningインストール後、Claude Code で/multica-mentioningを入力して読み込まれたか確認します。
同梱ファイルreferences/mentioning-source-map.md
詳細
メンションと委任
このスキルは、Multica バックエンドにおいてメンションリンクが何を行うかを、ソースに基づいて説明します。そもそもメンションすべきかどうか — ループの回避、確認応答時に沈黙を保つこと — については、ランタイムブリーフのメンションのセクションに記載されています。そちらに従い、ここでは繰り返しません。
以下のすべての記述は、references/mentioning-source-map.md のソースに紐付けられています。動作がこのドキュメントと異なる場合は、ソースマップで再確認してください。
メンションリンクは実際の UUID から構築されます
バックエンドがメンションを認識するのは、次の Markdown 形式によってのみです。
[@Label](mention://<type>/<id>)
パーサー(server/internal/util/mention.go 内の util.MentionRe)は、ちょうど 4 つの <type> 値と all センチネルを受け付け、<id> グループは 16 進文字とダッシュのみ、またはリテラル文字列 all のみを受け付けます。
(member|agent|squad|issue|all)/([0-9a-fA-F-]+|all)
つまり、リンク先は実際のエンティティ UUID(または all)であり、表示名ではありません。角括弧の間のラベルは自由なテキストです — 人間が読める名前を入れるのはそこです。
1 つの mention:// 形式は、意図的にこのパーサーの対象外に置かれています。
[Label](mention://project/<uuid>)。project は上記の type グループに存在しないため、バックエンドは決してこれをパースせず、何もキューに入れることはできません — これはすべてのクライアントがナビゲート可能にするレンダリング専用のリンクです(Web とデスクトップではチップ、モバイルではタップでプロジェクトを開く通常のリンク)。それがまさに要点です。プロジェクト参照は決して実行を開始できないようにすべきです。プロジェクトを指すために自由に使用してください(multica-projects-and-resources スキルを参照)。このドキュメントのその他の内容は、パーサーが認識する 4 つの型(および all)に関するものです。
ステップ 1 — --output json で UUID を調べる
名前は UUID ではありません。まず、対応するリストコマンドから UUID を調べてください。
- 人物 →
multica workspace member list --output json→user_idを使用 - エージェント →
multica agent list --output json→idを使用 - スクワッド →
multica squad list --output json→idを使用
人物の場合、メンション ID は user_id であり、メンバーシップ行の ID では ありません — バックエンド自身の名簿フォーマッターは、メンバーのメンションに user_id を使用します。表示名で照合してください。名前が曖昧または存在しない場合は、推測しないでください — 壊れたリンクを出力する代わりに、その旨をコメントに記載してください。
ステップ 2 — 4 つのタイプと、それぞれが正確に何をキューに入れるか
形式: [@Name](mention://<type>/<uuid>)。<type> と ID のソースは一致していなければなりません。そうでない場合、リンクは誤ったエンティティ(または何もない場所)に解決されます。
| 目的 | type | uuid の取得元 | バックエンドの動作 |
|---|---|---|---|
| エージェントをトリガーする | agent | agent.id | そのエージェントの実行をキューに入れます(EnqueueTaskForMention) |
| スクワッドに作業を引き渡す | squad | squad.id | スクワッドの leader_id を解決し、LEADER エージェントの実行をキューに入れます |
| 人をリンクする | member | member.user_id | リンクをレンダリングします。何もキューに入れません — エージェントの実行はなし |
| issue を参照する | issue | issue.id | リンクをレンダリングします。何もキューに入れません — 常に安全 |
メンショントリガーのセットは computeMentionedAgentCommentTriggers(server/internal/handler/comment.go)によって計算されます。コメントのパスはその結果を computeCommentAgentTriggers に折り込み、enqueueCommentAgentTriggers を介してキューに入れます。これは 2 つのタイプにのみ作用します。squad ブランチはスクワッドを解決し、そのリーダーをトリガーセットに追加します。その後、agent でないものはすべてスキップされ(if m.Type != "agent" { continue })、次に agent ブランチがそのエージェントを追加します。member または issue のメンションはどちらのブランチにも到達しないため、タスクをキューに入れません。
したがって、member メンションは人を「実行」させるものではなく、このスキルは Go のコメントハンドラーを介して通知を配信すると主張するものではありません — そのハンドラーにはそのようなコードパスは存在しません(ソースマップを参照)。検証されているのは上記の契約です。キューに作業を入れるのは agent と squad のメンションだけです。
プレビューとコメントごとの抑制
新しいクライアントは、コメントを作成または編集する前に POST /api/issues/{id}/comments/trigger-preview を呼び出すことができます。プレビューエンドポイントは、作成時および編集時の再トリガーと同じ computeCommentAgentTriggers 関数を使用するため、表示されるエージェントチップはクライアント側の再実装ではなく、バックエンドのルールから得られます。
編集をプレビューする場合、クライアントは editing_comment_id を送信できます。サーバーはそのコメントが同じワークスペースと issue に属することを検証し、編集の親コメントコンテキストを導出または確認し、trigger_comment_id がその同じコメントである保留中のタスクのみを除外します。その issue 上の他のコメントからの保留中のタスクは、引き続きプレビューを重複排除します。
コメントを作成または編集する場合、クライアントはオプションの suppress_agent_ids 配列を送信できます。サーバーはまず完全なトリガーセットを計算し、その後ポストフィルターとしてそれらのエージェント ID を削除します。フィールドが欠落しているか空の場合は、以前の動作が維持されます。計算されたトリガーセットに含まれない有効な UUID は何もしません。不正な形式の UUID はリクエスト境界で拒否されます。
@all はブロードキャストタイプです
@all はリテラルの all を使用し、UUID は決して使用しません:
[@all](mention://all/all)
これは issue 上の全員に宛てられます。特定のエージェントを実行させるものではありません。そしてトリガー時には特別です。@all メンションを含むコメントは、issue の担当者の自動オンメンショントリガー(およびその他の暗黙的なルーティングフォールバック — スレッドの親 / 会話のオーナー)を抑制するブロードキャストとして扱われます。@all は担当者に作業を依頼するためではなく、告知のために使用してください。
@all はそれらの暗黙的なルートのみを抑制します。同じコメント内の明示的な @agent / @squad メンションは通常どおり発火します(MUL-5411)。[@all](mention://all/all) お知らせ — [@Preflight](mention://agent/<uuid>) これをお願いします というコメントは Preflight をキューに入れ、他の誰も入れません。明示的なメンションはブロードキャストに優先します。server/internal/handler/comment.go の computeCommentAgentTriggers を参照してください。そこでは、明示的メンションのブランチが @all のショートサーキットよりも前に評価されます。
起こらないこと(結果に驚かないために)
これらはいずれも新しい実行を開始せず、エラー応答も返しません — ただし、これらは三つの異なる事象であり、応答がそのどれであるかを示します。パースされなかったメンションは、真に無言の no-op です。パースされたが拒否されたものは、trigger_outcomes の中で status: "blocked" と reason_code として返されます。対象がすでにビジー状態のものは coalesced または deferred として返されます。二度目の実行は行われませんが、あなたのコメントはすでに実行中のタスクに畳み込まれるため、それは依然として読まれます。投稿後にその配列を確認してください — これらが現れるのはそこだけです。
- UUID であるべき場所に名前がある。
mention://member/Aliceは無効です。id グループは hex とダッシュ、またはallのみを受け付けます。一般的な名前にある非 hex 文字によってパターン全体がマッチしなくなるため、パーサーは何も返しません。 - hex 風だが誤った UUID。 形式は正しく見えるがどのエンティティも所有していない UUID は、実際にはパースされ、その後ルックアップ時に no-op になります。ワークスペーススコープのクエリはエージェントを見つけられず、メンションは
invocation_not_allowedとしてブロックされたと報告されます。このコードは意図的に曖昧です — タイプミスの UUID と本物の権限拒否が意図的に同じに見える のは、入力した id が別のワークスペースのプライベートエージェントを指している可能性があり、その理由がその存在を確認してはならないからです。したがってinvocation_not_allowedを見たときは、可視性や呼び出し設定に触れる前に、UUID をライブロスターと照合してください(MUL-5548)。multica squad member list <squad-id> --output jsonは、メンションを組み立てるためのmember_idを返します。パターンにはマッチするが有効な UUID では全くない id(mention://agent/-)は、id パーサーによって拒否され、代わりにtarget_unavailableとしてブロックされます。非 UUID はどこにもエンティティを指名しないため、何も隠しません。どちらのケースもエラー応答になることは決してありません。 - すでに保留中のタスク。 たとえ正しい
@agent/@squadであっても、対象がこのイシュー上ですでに保留中のタスクを持っている場合(HasPendingTaskForIssueAndAgent)、二度目の実行は開始されません。これは破棄ではなく畳み込みです。コメントはそのタスクにマージされ、結果はcoalesced(同じレビュー済みヘッド)またはdeferred(異なるヘッド)になります — これを「メンションが機能しなかった」として再投稿しないでください。編集プレビューだけが唯一の例外です。editing_comment_idは、編集中の同じコメントからの保留中タスクを無視します。なぜなら、保存はトリガーを再計算する前にそれらの古いタスクをキャンセルするからです。それでもこれはコメントスコープであり、エージェント全体のバイパスではありません。 - アーカイブされたエージェント、またはランタイムがバインドされていないエージェント(同様に、そのリーダーがそうであるスクワッドも)は、それぞれ
target_unavailableとruntime_offlineでブロックされます。どちらも呼び出しゲートの後にのみチェックされるため、対象を呼び出せない呼び出し元がその状態を知ることは決してありません。 - 呼び出せないプライベートエージェント: ブロックされます — メンション経路は
@agentと@squadの両方でcanInvokeAgentをゲートします。これは 実行 ゲートであり、閲覧 ゲートではありません。MUL-3963 以降、UI でプライベートエージェントを開けるワークスペース管理者であっても、それをトリガーできない場合があります。そのため、対象を閲覧できることは、それをメンションできることについて何も示しません。(canEnqueueSquadLeaderラッパーはスクワッドの割り当て/昇格の経路であり、この経路ではありません。子完了による起床はゲートされません — multica-squads スキルを参照してください。)
イシューをまたぐチェーンは、その人間を保持します(MUL-6490)。A2A ゲートは、あなたのチェーンの最上位にいる人間を判定し、その人間はあなたが書くコメントに乗って移動します。コメントはそれを書いた実行を記録するため、それが起こす実行はあなたの起点者を継承します。これは、あなたが実行しているイシューとは異なるイシューにコメントする場合 — よくある「イシュー Y を作成し、そこで調整する」フロー — にも成り立ちます。したがって、自分のイシューで機能する委任は、作成したばかりのイシューでも機能し続けます。逆方向には成り立ちません。何かが別の人間(あなたのエージェントのオーナー、または対象イシューの起点者)に置き換わることは決してないため、チェーンの最上位に人間がいなければ、どのイシューに移動してもメンバースコープの許可リストは閉じたままです。
自動化に関する補足が1点あります(MUL-4857)。UNATTRIBUTED(未帰属)のautopilot実行(スケジュール/webhookディスパッチには人間の起票者が存在しないため、A2Aゲートには紐付ける人間がいません)が、autopilotが作成したissueで作業中に@mentionで委譲する場合、invokeゲートはautopilot作成者を実効的な起動ユーザーとしてフォールバックします。これは最初のディスパッチを許可した主体と同じです。したがって、実行途中の@agent / @squad委譲は、autopilot作成者がそのターゲットを起動できる場合(owner / public_toの一致)にのみ発火し、それ以外ではスキップされたままになります。これは認可のみに関するもので、エンキューされた実行の起票者/帰属は変更されません。
このフォールバックは検証済みのタスク系譜に束縛されます。つまり、委譲する実行自身のタスクがそのautopilot issueで作業しているもの(author == task agent、task.issue_id == このissue)である場合にのみ適用されるため、別の場所で作業している実行が、そのissueにコメントすることで別のautopilot作成者の権限を借用することは決してできません。
同じ権限は、通常の割り当てられたsquadリーダーの起床(autopilot issueへのワーカーの結果コメントが依然としてリーダーを起床できます)も担い、ターゲットがビジーであっても維持されます。メンションされたエージェントがすでに実行中の場合、委譲はその実行の完了時に同じ権限の下でリプレイされるため、失われることはありません。
編集は新規アクションとして扱われ、編集アクションからコメントの系譜を再導出します。エージェントの作成者が自身のコメントを編集する場合にのみ、系譜が編集タスクに再スタンプされます。それ以外の編集者——ワークスペースのowner/adminがエージェントのコメントを編集する場合を含む——はそれをクリアします。したがって、無関係なissueから古いautopilotコメントを編集したり、adminがエージェントのコメントを編集したりする場合(manage権限であり、invoke権限ではない)、元の実行の権限を再利用するのではなく、遅延されたcompletion-reconcileの時点でfail closedとなります。
誤り → 正しい
誤り: @alice please review
→ プレーンテキストであり、リンクもなく、何にもパースされず、誰にも届きません。
誤り: [@Alice](mention://member/Alice) please review
→ 「Alice」はUUIDではありません。idグループが非16進文字を拒否し、パターンが一致せず、リンクはサイレントに無効となります。
正しい:
multica workspace member list --output json→ Aliceのuser_id= 7f3a…[@Alice](mention://member/7f3a…) please review→ 実際のuser_idがパースされ、リンクがレンダリングされてAliceに解決されます。
@allブロードキャスト: [@all](mention://all/all) heads up — 全員に宛てて、特定のエージェントを実行せず、担当者の自動トリガーを抑制します。
これらの正確な形式は、Goの動作テスト(TestMentioningSkillTeachesTheParserContract)によって固定されており、これらをutil.ParseMentionsに通します。名前形式は何にもパースされず、実際のUUID形式はパースされ、@allは{all, all}にパースされ、実際のUUIDを伴う誤ったtypeでも依然としてパースされます(これが、typeがidソースと一致しなければならない理由です)。
参照
references/mentioning-source-map.md — 正規表現、エンキューブランチ、@all抑制、CLI idソースマッピングに関するfile:lineの根拠、およびGoのコメントハンドラーにメンバー通知の配信経路が存在しないことの明示的な注記を含みます。