Files

496 lines
19 KiB
Go

// Copyright 2026 Alibaba Group
// Licensed under the Apache License, Version 2.0 (the "License");
// Command multi-im-skill-chain verifies that reviewed high-frequency IM
// intents keep one default route across Skill references and Agent selection.
package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/app"
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli"
chatshortcut "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/shortcut/chat"
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/shortcut/chatmsg"
"github.com/spf13/cobra"
)
const manifestRelativePath = "scripts/policy/multi-im-skill-chain/testdata/intent_routes.json"
var (
intentIDPattern = regexp.MustCompile(`^[a-z0-9][a-z0-9._-]*$`)
reasonCodePattern = regexp.MustCompile(`^[a-z][a-z0-9_]*$`)
intentMarker = regexp.MustCompile(`<!--\s*dws-intent:\s*([a-z0-9][a-z0-9._-]*)\s*-->`)
mainGetwd = os.Getwd
mainExit = os.Exit
markerOpen = os.Open
buildEffective = cli.BuildEffectiveCommandRegistry
bindEffective = cli.BindEffectiveCommandRegistry
)
type routeManifest struct {
Version int `json:"version"`
MarkerRoots []string `json:"marker_roots"`
Intents []intentRoute `json:"intents"`
RetiredScripts []string `json:"retired_scripts"`
ContractReference string `json:"contract_reference"`
HandoffReference string `json:"handoff_reference"`
}
type intentRoute struct {
ID string `json:"id"`
PreferredTool string `json:"preferred_tool"`
AllowedFallbacks []routeFallback `json:"allowed_fallbacks,omitempty"`
ForbiddenDefaultTools []string `json:"forbidden_default_tools,omitempty"`
References []string `json:"references"`
}
type routeFallback struct {
Tool string `json:"tool"`
ReasonCode string `json:"reason_code"`
}
type toolFact struct {
Canonical string
PrimaryPath string
Confirmation string
UseWhen []string
AvoidWhen []string
HasMeta bool
}
func main() {
rootPath, err := mainGetwd()
if err != nil {
fmt.Fprintln(os.Stderr, err)
mainExit(2)
return
}
mainExit(run(rootPath, app.NewRootCommand(), os.Stdout, os.Stderr))
}
func run(rootPath string, root *cobra.Command, stdout, stderr io.Writer) int {
manifest, err := loadManifest(filepath.Join(rootPath, manifestRelativePath))
if err != nil {
fmt.Fprintln(stderr, err)
return 2
}
effective, err := buildEffective(root)
if err != nil {
fmt.Fprintf(stderr, "build effective CommandRegistry: %v\n", err)
return 2
}
bound, err := bindEffective(root, effective)
if err != nil {
fmt.Fprintf(stderr, "bind effective CommandRegistry: %v\n", err)
return 2
}
tools := make(map[string]toolFact, len(bound.ByCanonical))
for canonical, item := range bound.ByCanonical {
meta, ok := cli.ResolveMeta(item.PrimaryCLIPath)
tools[canonical] = toolFact{
Canonical: canonical,
PrimaryPath: item.PrimaryCLIPath,
Confirmation: meta.Safety.Confirmation,
UseWhen: append([]string(nil), meta.Selection.UseWhen...),
AvoidWhen: append([]string(nil), meta.Selection.AvoidWhen...),
HasMeta: ok,
}
}
failures := validateManifest(rootPath, manifest, tools)
sort.Strings(failures)
if len(failures) > 0 {
fmt.Fprintf(stderr, "multi IM Skill chain check failed (%d problems):\n", len(failures))
for _, failure := range failures {
fmt.Fprintf(stderr, " - %s\n", failure)
}
return 1
}
fmt.Fprintf(stdout, "multi IM Skill chain check: ok (%d intents)\n", len(manifest.Intents))
return 0
}
func loadManifest(path string) (routeManifest, error) {
data, err := os.ReadFile(path)
if err != nil {
return routeManifest{}, fmt.Errorf("read IM intent route manifest: %w", err)
}
decoder := json.NewDecoder(strings.NewReader(string(data)))
decoder.DisallowUnknownFields()
var manifest routeManifest
if err := decoder.Decode(&manifest); err != nil {
return routeManifest{}, fmt.Errorf("decode IM intent route manifest: %w", err)
}
return manifest, nil
}
func validateManifest(rootPath string, manifest routeManifest, tools map[string]toolFact) []string {
var failures []string
if manifest.Version != 3 {
failures = append(failures, fmt.Sprintf("manifest version = %d, want 3", manifest.Version))
}
if len(manifest.MarkerRoots) == 0 {
failures = append(failures, "manifest marker_roots must not be empty")
}
if len(manifest.Intents) == 0 {
failures = append(failures, "manifest intents must not be empty")
}
failures = append(failures, validateRetiredScripts(rootPath, manifest.RetiredScripts)...)
failures = append(failures, validateTypedContractReference(rootPath, manifest.ContractReference)...)
failures = append(failures, validateEventHandoffReference(rootPath, manifest.HandoffReference)...)
intentByID := make(map[string]intentRoute, len(manifest.Intents))
for _, route := range manifest.Intents {
if !intentIDPattern.MatchString(route.ID) {
failures = append(failures, fmt.Sprintf("intent id %q is invalid", route.ID))
continue
}
if _, exists := intentByID[route.ID]; exists {
failures = append(failures, fmt.Sprintf("duplicate intent id %q", route.ID))
continue
}
intentByID[route.ID] = route
preferred, ok := tools[route.PreferredTool]
if !ok {
failures = append(failures, fmt.Sprintf("intent %s preferred tool %q is absent from BoundCommandRegistry", route.ID, route.PreferredTool))
continue
}
if !preferred.HasMeta || preferred.Confirmation == "" {
failures = append(failures, fmt.Sprintf("intent %s preferred tool %q is absent from ResolveMeta delivery", route.ID, route.PreferredTool))
}
if len(preferred.UseWhen) == 0 || len(preferred.AvoidWhen) == 0 {
failures = append(failures, fmt.Sprintf("intent %s preferred tool %q needs non-empty use_when and avoid_when", route.ID, route.PreferredTool))
}
seenFallbacks := map[string]bool{}
for _, fallback := range route.AllowedFallbacks {
if fallback.Tool == "" || seenFallbacks[fallback.Tool] {
failures = append(failures, fmt.Sprintf("intent %s has empty or duplicate allowed fallback %q", route.ID, fallback.Tool))
continue
}
seenFallbacks[fallback.Tool] = true
if !reasonCodePattern.MatchString(fallback.ReasonCode) {
failures = append(failures, fmt.Sprintf("intent %s fallback %q has invalid reason_code %q", route.ID, fallback.Tool, fallback.ReasonCode))
}
fact, exists := tools[fallback.Tool]
if !exists {
failures = append(failures, fmt.Sprintf("intent %s fallback tool %q is absent from BoundCommandRegistry", route.ID, fallback.Tool))
continue
}
if !fact.HasMeta || fact.Confirmation == "" {
failures = append(failures, fmt.Sprintf("intent %s fallback tool %q is absent from ResolveMeta delivery", route.ID, fallback.Tool))
} else if fact.Confirmation != preferred.Confirmation {
failures = append(failures, fmt.Sprintf("intent %s fallback %q confirmation %q differs from preferred %q confirmation %q", route.ID, fallback.Tool, fact.Confirmation, route.PreferredTool, preferred.Confirmation))
}
}
seenForbidden := map[string]bool{}
for _, canonical := range route.ForbiddenDefaultTools {
if canonical == "" || seenForbidden[canonical] {
failures = append(failures, fmt.Sprintf("intent %s has empty or duplicate forbidden default %q", route.ID, canonical))
continue
}
seenForbidden[canonical] = true
entry, exists := tools[canonical]
if !exists {
failures = append(failures, fmt.Sprintf("intent %s forbidden default tool %q is absent from BoundCommandRegistry", route.ID, canonical))
continue
}
if !entry.HasMeta || entry.Confirmation == "" {
failures = append(failures, fmt.Sprintf("intent %s forbidden default tool %q is absent from ResolveMeta delivery", route.ID, canonical))
}
if len(entry.UseWhen) == 0 || len(entry.AvoidWhen) == 0 {
failures = append(failures, fmt.Sprintf("intent %s forbidden default tool %q needs non-empty use_when and avoid_when", route.ID, canonical))
}
}
seenReferences := map[string]bool{}
for _, reference := range route.References {
if !safeRepositoryPath(reference) || filepath.Ext(reference) != ".md" {
failures = append(failures, fmt.Sprintf("intent %s has invalid reference %q", route.ID, reference))
continue
}
if seenReferences[reference] {
failures = append(failures, fmt.Sprintf("intent %s repeats reference %q", route.ID, reference))
continue
}
seenReferences[reference] = true
if _, err := os.Stat(filepath.Join(rootPath, filepath.FromSlash(reference))); err != nil {
failures = append(failures, fmt.Sprintf("intent %s reference %q does not exist", route.ID, reference))
}
}
}
markerFailures, markers := scanMarkers(rootPath, manifest.MarkerRoots, intentByID, tools)
failures = append(failures, markerFailures...)
for _, route := range manifest.Intents {
for _, reference := range route.References {
key := route.ID + "\x00" + filepath.ToSlash(reference)
switch markers[key] {
case 0:
failures = append(failures, fmt.Sprintf("intent %s reference %s is missing its dws-intent marker", route.ID, reference))
case 1:
default:
failures = append(failures, fmt.Sprintf("intent %s reference %s has %d dws-intent markers, want 1", route.ID, reference, markers[key]))
}
}
}
return failures
}
func validateRetiredScripts(rootPath string, paths []string) []string {
var failures []string
if len(paths) == 0 {
return []string{"manifest retired_scripts must not be empty"}
}
seen := map[string]bool{}
for _, path := range paths {
if !safeRepositoryPath(path) || filepath.Ext(path) != ".py" {
failures = append(failures, fmt.Sprintf("invalid retired script path %q", path))
continue
}
if seen[path] {
failures = append(failures, fmt.Sprintf("duplicate retired script path %q", path))
continue
}
seen[path] = true
if _, err := os.Stat(filepath.Join(rootPath, filepath.FromSlash(path))); err == nil {
failures = append(failures, fmt.Sprintf("retired script %s was republished", path))
} else if !os.IsNotExist(err) {
failures = append(failures, fmt.Sprintf("inspect retired script %s: %v", path, err))
}
}
return failures
}
func validateTypedContractReference(rootPath, relative string) []string {
if !safeRepositoryPath(relative) || filepath.Ext(relative) != ".md" {
return []string{fmt.Sprintf("invalid contract_reference %q", relative)}
}
data, err := os.ReadFile(filepath.Join(rootPath, filepath.FromSlash(relative)))
if err != nil {
return []string{fmt.Sprintf("read typed contract reference %s: %v", relative, err)}
}
data = bytes.ReplaceAll(data, []byte("\r\n"), []byte("\n"))
blocks := []struct {
name string
expected string
}{
{name: "MESSAGE_RESULT", expected: renderMessageResultContract()},
{name: "IDENTITY_CAPABILITY", expected: renderIdentityCapabilityContract()},
{name: "CARD_WORKFLOW", expected: renderCardWorkflowContract()},
{name: "CAPABILITY_BOUNDARY", expected: renderCapabilityBoundaryContract()},
}
var failures []string
for _, block := range blocks {
start := "<!-- DWS_" + block.name + "_CONTRACT_START -->"
end := "<!-- DWS_" + block.name + "_CONTRACT_END -->"
expected := start + "\n" + block.expected + "\n" + end
if bytes.Count(data, []byte(start)) != 1 || bytes.Count(data, []byte(end)) != 1 {
failures = append(failures, fmt.Sprintf("%s must contain exactly one %s contract marker pair", relative, block.name))
continue
}
startAt := bytes.Index(data, []byte(start))
endAt := bytes.Index(data[startAt:], []byte(end))
if endAt < 0 {
failures = append(failures, fmt.Sprintf("%s has malformed %s contract markers", relative, block.name))
continue
}
actual := string(data[startAt : startAt+endAt+len(end)])
if actual != expected {
failures = append(failures, fmt.Sprintf("%s %s contract differs from Runtime typed descriptor", relative, block.name))
}
}
return failures
}
func validateEventHandoffReference(rootPath, relative string) []string {
if !safeRepositoryPath(relative) || filepath.Ext(relative) != ".md" {
return []string{fmt.Sprintf("invalid handoff_reference %q", relative)}
}
data, err := os.ReadFile(filepath.Join(rootPath, filepath.FromSlash(relative)))
if err != nil {
return []string{fmt.Sprintf("read event handoff reference %s: %v", relative, err)}
}
data = bytes.ReplaceAll(data, []byte("\r\n"), []byte("\n"))
const expected = `<!-- DWS_EVENT_CHAT_HANDOFF_START -->
| event field | exact chat target |
|---|---|
| ` + "`conversation_id`" + ` | ` + "`dws chat +messages-send --as user --group <conversation_id>`" + ` |
| ` + "`sender_open_dingtalk_id`" + ` | ` + "`dws chat +messages-send --as user --open-dingtalk-id <sender_open_dingtalk_id>`" + ` |
<!-- DWS_EVENT_CHAT_HANDOFF_END -->`
start := bytes.Index(data, []byte("<!-- DWS_EVENT_CHAT_HANDOFF_START -->"))
endMarker := "<!-- DWS_EVENT_CHAT_HANDOFF_END -->"
if start < 0 || bytes.Count(data, []byte("<!-- DWS_EVENT_CHAT_HANDOFF_START -->")) != 1 ||
bytes.Count(data, []byte(endMarker)) != 1 {
return []string{fmt.Sprintf("%s must contain exactly one event-to-chat handoff marker pair", relative)}
}
end := bytes.Index(data[start:], []byte(endMarker))
if end < 0 || string(data[start:start+end+len(endMarker)]) != expected {
return []string{fmt.Sprintf("%s event-to-chat handoff differs from exact stable-ID mapping", relative)}
}
return nil
}
func renderMessageResultContract() string {
contract := chatmsg.CurrentMessageResultContract()
return fmt.Sprintf("- `version`: `%s`\n- `message_fields`: %s\n- `envelope_fields`: %s",
contract.Version, markdownCodeList(contract.MessageFields), markdownCodeList(contract.EnvelopeFields))
}
func renderIdentityCapabilityContract() string {
var rows []string
for _, capability := range chatshortcut.MessageIdentityCapabilities() {
rows = append(rows, fmt.Sprintf("| `%s` | %s | %s | %s | %s | `%t` | `%t` |",
capability.Identity, markdownBreakList(capability.Targets), markdownBreakList(capability.ContentTypes),
markdownBreakList(capability.NaturalTargets), markdownBreakList(capability.MentionTargets),
capability.IdempotencyKeys, capability.BatchLedger))
}
return "| identity | targets | content types | natural targets | mention targets | idempotency keys | batch ledger |\n" +
"|---|---|---|---|---|---:|---:|\n" + strings.Join(rows, "\n")
}
func renderCardWorkflowContract() string {
contract := chatshortcut.CurrentCardWorkflowContract()
statuses := make([]string, 0, len(contract.FlowStatuses))
for _, status := range contract.FlowStatuses {
statuses = append(statuses, fmt.Sprintf("%d=%s", status.Value, status.Name))
}
return fmt.Sprintf("- `version`: `%s`\n- `targets`: %s\n- `content_types`: %s\n- `flow_statuses`: %s\n- `callback_supported`: `%t`",
contract.Version, markdownCodeList(contract.Targets), markdownCodeList(contract.ContentTypes),
markdownCodeList(statuses), contract.CallbackSupported)
}
func renderCapabilityBoundaryContract() string {
rows := make([]string, 0)
for _, boundary := range chatshortcut.CurrentIMCapabilityBoundaries() {
rows = append(rows, fmt.Sprintf("| `%s` | `%t` | %s |", boundary.Capability, boundary.Supported, boundary.Alternative))
}
return "| capability | supported | current route / boundary |\n|---|---:|---|\n" + strings.Join(rows, "\n")
}
func markdownCodeList(values []string) string {
if len(values) == 0 {
return "—"
}
quoted := make([]string, len(values))
for index, value := range values {
quoted[index] = "`" + value + "`"
}
return strings.Join(quoted, ", ")
}
func markdownBreakList(values []string) string {
if len(values) == 0 {
return "—"
}
quoted := make([]string, len(values))
for index, value := range values {
quoted[index] = "`" + value + "`"
}
return strings.Join(quoted, "<br>")
}
func scanMarkers(rootPath string, roots []string, intents map[string]intentRoute, tools map[string]toolFact) ([]string, map[string]int) {
var failures []string
markers := map[string]int{}
for _, relativeRoot := range roots {
if !safeRepositoryPath(relativeRoot) {
failures = append(failures, fmt.Sprintf("invalid marker root %q", relativeRoot))
continue
}
absoluteRoot := filepath.Join(rootPath, filepath.FromSlash(relativeRoot))
err := filepath.WalkDir(absoluteRoot, func(path string, entry fs.DirEntry, walkErr error) error {
if walkErr != nil {
return walkErr
}
if entry.IsDir() || filepath.Ext(path) != ".md" {
return nil
}
file, err := markerOpen(path)
if err != nil {
return err
}
defer file.Close()
relative, _ := filepath.Rel(rootPath, path)
relative = filepath.ToSlash(relative)
scanner := bufio.NewScanner(file)
scanner.Buffer(make([]byte, 64*1024), 4*1024*1024)
lineNumber := 0
for scanner.Scan() {
lineNumber++
line := scanner.Text()
for _, match := range intentMarker.FindAllStringSubmatch(line, -1) {
id := match[1]
route, ok := intents[id]
if !ok {
failures = append(failures, fmt.Sprintf("%s:%d uses unknown dws-intent %q", relative, lineNumber, id))
continue
}
if !stringSliceContains(route.References, relative) {
failures = append(failures, fmt.Sprintf("%s:%d uses undeclared dws-intent %q", relative, lineNumber, id))
}
markers[id+"\x00"+relative]++
preferred, exists := tools[route.PreferredTool]
if !exists {
continue
}
if !containsCLIPath(line, preferred.PrimaryPath) {
failures = append(failures, fmt.Sprintf("%s:%d intent %s must contain preferred path `dws %s` on the marker line", relative, lineNumber, id, preferred.PrimaryPath))
}
for _, canonical := range route.ForbiddenDefaultTools {
if fact, ok := tools[canonical]; ok && containsCLIPath(line, fact.PrimaryPath) {
failures = append(failures, fmt.Sprintf("%s:%d intent %s uses forbidden default `dws %s`", relative, lineNumber, id, fact.PrimaryPath))
}
}
}
}
return scanner.Err()
})
if err != nil {
failures = append(failures, fmt.Sprintf("scan marker root %s: %v", relativeRoot, err))
}
}
return failures, markers
}
func safeRepositoryPath(path string) bool {
path = filepath.ToSlash(strings.TrimSpace(path))
return path != "" && path != "." && !filepath.IsAbs(path) && path != ".." && !strings.HasPrefix(path, "../") && !strings.Contains(path, "/../")
}
func containsCLIPath(line, path string) bool {
needle := "dws " + strings.TrimSpace(path)
index := strings.Index(line, needle)
if index < 0 {
return false
}
end := index + len(needle)
if end == len(line) {
return true
}
next := line[end]
return next == ' ' || next == '`' || next == '<' || next == '|' || next == ','
}
func stringSliceContains(values []string, target string) bool {
for _, value := range values {
if filepath.ToSlash(value) == target {
return true
}
}
return false
}