Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions internal/skilldoc/source_cards_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package skilldoc

import (
"os"
"strings"
"testing"
)

func TestChannelCardDisambiguatesFlashcatWorkspace(t *testing.T) {
body, err := os.ReadFile("../../skills/flashduty/reference/channel.md")
if err != nil {
t.Fatal(err)
}
text := string(body)
for _, want := range []string{
"协作空间",
"Flashcat workspace",
"灭火图",
"firemap",
"do not silently switch",
} {
if !strings.Contains(text, want) {
t.Errorf("channel card must disambiguate Flashduty channel vs Flashcat workspace; missing %q", want)
}
}
}
3 changes: 3 additions & 0 deletions skills/flashduty/reference/channel.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Prereq: `SKILL.md` read. **SKILL.md + this card = full competence on channels

"协作空间 / 频道 / 渠道 / 告警分组 / 降噪 / 静默 / 抑制 / 丢弃 / 升级策略 / 告警收敛 / channel / collaboration space / escalation rule / silence / inhibit / drop rule" → **channel**, NOT `incident` (incidents live _inside_ a channel) or `alert` (alerts are routed _into_ a channel). **`协作空间` (collaboration space) IS the `channel` API noun** — a naive translation would be "频道", but Flashduty's product surfaces it as 协作空间. Key IDs: **`channel-id` (int)** from `channel list`; **`rule-id` (MongoDB ObjectID string)** from `escalate-rule-list`, `inhibit-rule-list`, `silence-rule-list`, `unsubscribe-rule-list`.

**Flashcat workspace exception.** When the user asks whether a "空间" is healthy, red/green, or specifically mentions **灭火图 / firemap**, do not assume they mean a Flashduty channel. In that context, "空间" may be a **Flashcat workspace**, and the answer must come from the Flashcat/firemap surface rather than channel incident stats. If you first resolved a name as a Flashduty `channel-id` and later resolve the same visible name as a Flashcat `workspace-id`, **do not silently switch** — tell the user these are different objects and state which ID/surface each conclusion uses.

## Intent → verb

| want | verb |
Expand Down Expand Up @@ -38,6 +40,7 @@ fduty channel create --channel-name "production-api" --team-id <team-id> \
# → returns channel_id; use it below

# 3. add an escalation rule (all flags; layers is required via --data)
# API field `person_ids` expects member IDs from `fduty member list`.
fduty channel escalate-rule-create \
--channel-id <channel-id> --rule-name "P1 on-call" --template-id <template-id> \
--data '{"layers":[{"target":{"person_ids":[<member-id>],"by":{"critical":["voice","sms"],"warning":["feishu"]}},"notify_step":5,"max_times":3,"escalate_window":30}]}'
Expand Down
Loading