Files
玉澜 b1cefba808 refactor(schema): retire reviewed registry; collector is the single identity source
Phase 3 of identity-deregistry. BuildEffectiveCommandRegistry now builds the
EffectiveCommandRegistry from CollectIdentitySpecs(root) instead of the
embedded reviewed registry, and the registry source is removed atomically:

- delete internal/cli/schema_command_registry/ (registry.json + products/),
  schema_command_registry.schema.json, the three //go:embed directives, and
  the registry-only loaders/validators (loadReviewedCommandRegistry,
  decodeCommandRegistry, ValidateCommandRegistrySource, shard assemble/merge
  helpers, ReviewedCommandRegistryMergedJSON/SourceHash, ReviewedCommandSpecs)
- keep CommandSpec/CommandRegistry/EffectiveCommandRegistry,
  newEffectiveCommandRegistry/indexCommandSpecs, and SourceHash; the
  collector-built effective hash is byte-identical to the reviewed one, so
  catalog surface_hash/source_hash are unchanged
- convert the Phase 2 dual-run gate into TestCollectedIdentityIsValidSingleSource:
  collected specs non-empty, no missing primaries, effective build succeeds,
  SourceHash stable across repeated collection walks
- generators: catalog -surface and agent-metadata -registry/-surface become
  fail-closed retired valves; outputguard no longer protects the registry
  paths; fetch_mcp_metadata derives interface refs from collected identity
  instead of the merged registry JSON
- retire scripts/policy/check-schema-command-registry.sh and its Makefile
  invocation; generate-schema/check-generated-drift now fail closed if
  schema_command_registry/ reappears
- update AGENTS.md, docs/reference.md, and in-code reviewed-input notes
2026-08-03 16:18:20 +08:00

423 lines
17 KiB
Go

// Copyright 2026 Alibaba Group
// Licensed under the Apache License, Version 2.0 (the "License");
package cli
import (
"encoding/json"
"reflect"
"sort"
"strings"
"testing"
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd/contract"
"github.com/spf13/cobra"
)
func TestDeliveryRuntimeSchemaExclusionsAreReviewedExact(t *testing.T) {
exclusions, err := ReviewedRuntimeSchemaExclusions()
if err != nil {
t.Fatal(err)
}
if len(exclusions) == 0 {
t.Fatal("reviewed runtime schema exclusions must not be empty")
}
seen := map[string]bool{}
for _, exclusion := range exclusions {
if !exclusion.Reviewed || strings.TrimSpace(exclusion.Reason) == "" {
t.Fatalf("unreviewed exclusion: %#v", exclusion)
}
path := normalizeSchemaCLIPath(exclusion.CLIPath)
if path == "" || path != exclusion.CLIPath {
t.Fatalf("exclusion path must be normalized and non-empty: %#v", exclusion)
}
if seen[path] {
t.Fatalf("duplicate exclusion %q", path)
}
seen[path] = true
}
for _, group := range reviewedRuntimeSchemaExclusionGroups {
if strings.TrimSpace(group.ID) == "" || !group.Reviewed || strings.TrimSpace(group.Reason) == "" {
t.Fatalf("invalid exclusion group: %#v", group)
}
if len(group.Commands) == 0 {
t.Fatalf("exclusion group %q has no commands", group.ID)
}
}
}
func TestRuntimeSchemaCompletenessRequiresCoverageOrReviewedExclusion(t *testing.T) {
root := &cobra.Command{Use: "dws"}
covered := &cobra.Command{Use: "covered", Run: func(*cobra.Command, []string) {}}
missing := &cobra.Command{Use: "missing", Run: func(*cobra.Command, []string) {}}
excluded := &cobra.Command{Use: "excluded", Run: func(*cobra.Command, []string) {}}
hidden := &cobra.Command{Use: "hidden", Hidden: true, Run: func(*cobra.Command, []string) {}}
AttachRuntimeSchema(covered, "sample", "covered", "test")
root.AddCommand(covered, missing, excluded, hidden)
report := runtimeSchemaCompletenessForTest(root, []RuntimeSchemaExclusion{{
CLIPath: "excluded", Reason: "reviewed test exclusion", Reviewed: true,
}})
if !reflect.DeepEqual(report.Covered, []string{"covered"}) {
t.Fatalf("covered = %v", report.Covered)
}
if !reflect.DeepEqual(report.Excluded, []string{"excluded"}) {
t.Fatalf("excluded = %v", report.Excluded)
}
if !reflect.DeepEqual(report.Missing, []string{"missing"}) {
t.Fatalf("missing = %v", report.Missing)
}
if len(report.InvalidExclusions) != 0 || len(report.StaleExclusions) != 0 {
t.Fatalf("invalid=%v stale=%v", report.InvalidExclusions, report.StaleExclusions)
}
}
func TestRuntimeSchemaCompletenessRejectsInvalidAndStaleExclusions(t *testing.T) {
root := &cobra.Command{Use: "dws"}
current := &cobra.Command{Use: "current", Run: func(*cobra.Command, []string) {}}
covered := &cobra.Command{Use: "covered", Run: func(*cobra.Command, []string) {}}
AttachRuntimeSchema(covered, "sample", "covered", "test")
root.AddCommand(current, covered)
report := runtimeSchemaCompletenessForTest(root, []RuntimeSchemaExclusion{
{CLIPath: "current", Reason: "", Reviewed: true},
{CLIPath: "stale", Reason: "reviewed but obsolete", Reviewed: true},
{CLIPath: "covered", Reason: "no longer needed", Reviewed: true},
})
if !reflect.DeepEqual(report.InvalidExclusions, []string{"current"}) {
t.Fatalf("invalid = %v", report.InvalidExclusions)
}
if !reflect.DeepEqual(report.StaleExclusions, []string{"covered", "stale"}) {
t.Fatalf("stale = %v", report.StaleExclusions)
}
if !reflect.DeepEqual(report.Missing, []string{"current"}) {
t.Fatalf("missing = %v", report.Missing)
}
}
func TestEffectiveCommandRegistryOwnsIdentityWithoutNativeAnnotation(t *testing.T) {
root := &cobra.Command{Use: "dws"}
product := &cobra.Command{Use: "aisearch"}
leaf := &cobra.Command{Use: "person", Run: func(*cobra.Command, []string) {}}
product.AddCommand(leaf)
root.AddCommand(product)
spec := CommandSpec{
CanonicalPath: "aisearch.enterprise_person_search",
PrimaryCLIPath: "aisearch person",
}
effective, err := newEffectiveCommandRegistry([]CommandSpec{spec})
if err != nil {
t.Fatal(err)
}
bound, err := BindEffectiveCommandRegistry(root, effective)
if err != nil {
t.Fatal(err)
}
entries, err := collectRuntimeSchemaEntriesFromBound(bound)
if err != nil || len(entries) != 1 || entries[0].ProductID+"."+entries[0].ToolName != spec.CanonicalPath {
t.Fatalf("registry-owned entries = %#v, err=%v", entries, err)
}
AttachRuntimeSchema(leaf, "aisearch", "wrong_identity", "test")
if _, err := BindEffectiveCommandRegistry(root, effective); err == nil || !strings.Contains(err.Error(), "conflicts with native annotation") {
t.Fatalf("native mismatch error = %v", err)
}
}
func TestSchemaCatalogDeliveryCompletenessRejectsAnnotatedLeafOutsideSurface(t *testing.T) {
root := &cobra.Command{Use: "dws"}
product := &cobra.Command{Use: "sample"}
covered := &cobra.Command{Use: "covered", Run: func(*cobra.Command, []string) {}}
omitted := &cobra.Command{Use: "omitted", Run: func(*cobra.Command, []string) {}}
AttachRuntimeSchema(covered, "sample", "covered", "test")
AttachRuntimeSchema(omitted, "sample", "omitted", "test")
product.AddCommand(covered, omitted)
root.AddCommand(product)
annotationReport := runtimeSchemaCompletenessForTest(root, nil)
if !reflect.DeepEqual(annotationReport.Covered, []string{"sample covered", "sample omitted"}) || len(annotationReport.Missing) != 0 {
t.Fatalf("annotation report = %#v", annotationReport)
}
snapshot := schemaDeliveryTestSnapshot(schemaDeliveryTestTool{
Canonical: "sample.covered", CLIPath: "sample covered",
})
report := schemaCatalogDeliveryCompletenessForTest(root, snapshot, nil)
if !reflect.DeepEqual(report.Covered, []string{"sample covered"}) {
t.Fatalf("covered = %v", report.Covered)
}
if !reflect.DeepEqual(report.Missing, []string{"sample omitted"}) {
t.Fatalf("missing = %v", report.Missing)
}
}
func TestSchemaCatalogDeliveryCompletenessAcceptsExactReviewedExclusion(t *testing.T) {
root := &cobra.Command{Use: "dws"}
product := &cobra.Command{Use: "sample"}
covered := &cobra.Command{Use: "covered", Run: func(*cobra.Command, []string) {}}
excluded := &cobra.Command{Use: "excluded", Run: func(*cobra.Command, []string) {}}
AttachRuntimeSchema(covered, "sample", "covered", "test")
product.AddCommand(covered, excluded)
root.AddCommand(product)
snapshot := schemaDeliveryTestSnapshot(schemaDeliveryTestTool{
Canonical: "sample.covered", CLIPath: "sample covered",
})
report := schemaCatalogDeliveryCompletenessForTest(root, snapshot, []RuntimeSchemaExclusion{{
CLIPath: "sample excluded", Reason: "reviewed test exclusion", Reviewed: true,
}})
if !reflect.DeepEqual(report.Covered, []string{"sample covered"}) ||
!reflect.DeepEqual(report.Excluded, []string{"sample excluded"}) ||
len(report.Missing) != 0 || len(report.StaleExclusions) != 0 {
t.Fatalf("delivery report = %#v", report)
}
}
func TestSchemaCatalogDeliveryCompletenessAcceptsDeliveredAlias(t *testing.T) {
root := &cobra.Command{Use: "dws"}
product := &cobra.Command{Use: "sample"}
current := &cobra.Command{Use: "current", Hidden: true, Run: func(*cobra.Command, []string) {}}
legacy := &cobra.Command{Use: "legacy", Run: func(*cobra.Command, []string) {}}
annotateTestCompatibilityPair(current, legacy)
AttachRuntimeSchema(current, "sample", "current", "test")
AttachRuntimeSchema(legacy, "sample", "current", "test")
product.AddCommand(current, legacy)
root.AddCommand(product)
snapshot := schemaDeliveryTestSnapshot(schemaDeliveryTestTool{
Canonical: "sample.current", CLIPath: "sample current", Aliases: []string{"sample legacy"},
})
report := schemaCatalogDeliveryCompletenessForTest(root, snapshot, nil)
if !reflect.DeepEqual(report.Covered, []string{"sample legacy"}) || len(report.Missing) != 0 {
t.Fatalf("delivery report = %#v", report)
}
}
func TestSchemaCatalogDeliveryCompletenessRejectsWrongCanonical(t *testing.T) {
root := schemaDeliveryTestRoot(
schemaDeliveryTestTool{Canonical: "sample.expected", CLIPath: "sample run"},
)
snapshot := schemaDeliveryTestSnapshot(schemaDeliveryTestTool{
Canonical: "sample.wrong", CLIPath: "sample run",
})
report := schemaCatalogDeliveryCompletenessForTest(root, snapshot, nil)
if !reflect.DeepEqual(report.Missing, []string{"sample run"}) {
t.Fatalf("missing = %v", report.Missing)
}
if len(report.DeliveryErrors) == 0 {
t.Fatal("wrong canonical passed final delivery validation")
}
}
func TestSchemaCatalogDeliveryCompletenessRejectsMissingFinalLookup(t *testing.T) {
root := schemaDeliveryTestRoot(
schemaDeliveryTestTool{Canonical: "sample.delivered", CLIPath: "sample delivered"},
schemaDeliveryTestTool{Canonical: "sample.missing", CLIPath: "sample missing"},
)
snapshot := schemaDeliveryTestSnapshot(schemaDeliveryTestTool{
Canonical: "sample.delivered", CLIPath: "sample delivered",
})
report := schemaCatalogDeliveryCompletenessForTest(root, snapshot, nil)
if !reflect.DeepEqual(report.Covered, []string{"sample delivered"}) || !reflect.DeepEqual(report.Missing, []string{"sample missing"}) {
t.Fatalf("delivery report = %#v", report)
}
}
func TestSchemaCatalogDeliveryCompletenessRejectsAliasCollision(t *testing.T) {
root := schemaDeliveryTestRoot(
schemaDeliveryTestTool{Canonical: "sample.one", CLIPath: "sample one"},
schemaDeliveryTestTool{Canonical: "sample.two", CLIPath: "sample two"},
)
snapshot := schemaDeliveryTestSnapshot(
schemaDeliveryTestTool{Canonical: "sample.one", CLIPath: "sample one", Aliases: []string{"sample shared"}},
schemaDeliveryTestTool{Canonical: "sample.two", CLIPath: "sample two"},
)
// Corrupt the serialized delivery boundary after building a valid typed
// registry. SchemaRegistry itself rejects this state at construction time;
// the production loader must reject the same collision after decoding.
snapshot.Tools["sample.two"]["aliases"] = []string{"sample shared"}
for _, product := range snapshot.Catalog["products"].([]map[string]any) {
for _, tool := range product["tools"].([]map[string]any) {
if schemaString(tool["canonical_path"]) == "sample.two" {
tool["aliases"] = []string{"sample shared"}
}
}
}
snapshot.SourceHash = schemaCatalogSnapshotHash(snapshot)
report := schemaCatalogDeliveryCompletenessForTest(root, snapshot, nil)
if len(report.DeliveryErrors) != 1 || (!strings.Contains(report.DeliveryErrors[0], "resolves to both") && !strings.Contains(report.DeliveryErrors[0], "claimed by both")) {
t.Fatalf("delivery errors = %v", report.DeliveryErrors)
}
}
func TestSchemaCatalogDeliveryCompletenessRejectsPhantomAlias(t *testing.T) {
tool := schemaDeliveryTestTool{Canonical: "sample.run", CLIPath: "sample run", Aliases: []string{"sample ghost"}}
root := schemaDeliveryTestRoot(schemaDeliveryTestTool{Canonical: tool.Canonical, CLIPath: tool.CLIPath})
report := schemaCatalogDeliveryCompletenessForTest(root, schemaDeliveryTestSnapshot(tool), nil)
if len(report.DeliveryErrors) != 1 || !strings.Contains(report.DeliveryErrors[0], "non-executable Schema path") {
t.Fatalf("delivery errors = %v", report.DeliveryErrors)
}
}
func TestSchemaCatalogDeliveryCompletenessRejectsSummaryLeafDrift(t *testing.T) {
snapshot := schemaDeliveryTestSnapshot(schemaDeliveryTestTool{Canonical: "sample.run", CLIPath: "sample run"})
snapshot.Catalog["products"].([]map[string]any)[0]["tools"].([]map[string]any)[0]["primary_cli_path"] = "sample drift"
snapshot.SourceHash = schemaCatalogSnapshotHash(snapshot)
report := schemaCatalogDeliveryCompletenessForTest(schemaDeliveryTestRoot(schemaDeliveryTestTool{Canonical: "sample.run", CLIPath: "sample run"}), snapshot, nil)
if len(report.DeliveryErrors) != 1 || (!strings.Contains(report.DeliveryErrors[0], "disagrees with full leaf") && !strings.Contains(report.DeliveryErrors[0], "changed product/tool summaries")) {
t.Fatalf("delivery errors = %v", report.DeliveryErrors)
}
}
func TestSchemaCatalogDeliveryCompletenessRejectsProvenanceDrift(t *testing.T) {
snapshot := schemaDeliveryTestSnapshot(schemaDeliveryTestTool{Canonical: "sample.run", CLIPath: "sample run"})
provenance := snapshot.Tools["sample.run"]["field_provenance"].(map[string]any)
canonical := provenance["canonical_path"].(map[string]any)
canonical["value"] = "sample.wrong"
snapshot.SourceHash = schemaCatalogSnapshotHash(snapshot)
report := schemaCatalogDeliveryCompletenessForTest(schemaDeliveryTestRoot(schemaDeliveryTestTool{
Canonical: "sample.run", CLIPath: "sample run",
}), snapshot, nil)
if len(report.DeliveryErrors) != 1 || !strings.Contains(report.DeliveryErrors[0], "provenance winner does not equal final value") {
t.Fatalf("delivery errors = %v", report.DeliveryErrors)
}
}
func TestSchemaCatalogDeliveryCompletenessRoundTripsThroughProductionLoader(t *testing.T) {
tool := schemaDeliveryTestTool{Canonical: "sample.run", CLIPath: "sample run"}
if err := validateSchemaCatalogDeliveryCompletenessForTest(schemaDeliveryTestRoot(tool), schemaDeliveryTestSnapshot(tool), nil); err != nil {
t.Fatalf("valid final delivery: %v", err)
}
}
type schemaDeliveryTestTool struct {
Canonical string
CLIPath string
Aliases []string
Parameters []ParameterSpec
Selection contract.SelectionSpec
}
func schemaDeliveryTestRoot(tools ...schemaDeliveryTestTool) *cobra.Command {
root := &cobra.Command{Use: "dws"}
products := map[string]*cobra.Command{}
for _, tool := range tools {
parts := strings.SplitN(tool.Canonical, ".", 2)
product := products[parts[0]]
if product == nil {
product = &cobra.Command{Use: parts[0]}
products[parts[0]] = product
root.AddCommand(product)
}
pathParts := strings.Fields(tool.CLIPath)
leaf := &cobra.Command{Use: pathParts[len(pathParts)-1], Run: func(*cobra.Command, []string) {}}
AttachRuntimeSchema(leaf, parts[0], parts[1], "test")
product.AddCommand(leaf)
}
return root
}
func schemaDeliveryTestSnapshot(tools ...schemaDeliveryTestTool) SchemaCatalogSnapshot {
registry := schemaDeliveryTestRegistry(tools...)
payload, err := registry.ToSnapshotPayload()
if err != nil {
panic(err)
}
snapshot := SchemaCatalogSnapshot{
Version: SchemaCatalogSnapshotVersion,
Catalog: payload.Catalog,
Tools: payload.Tools,
}
snapshot.SourceHash = schemaCatalogSnapshotHash(snapshot)
return snapshot
}
func schemaDeliveryTestRegistry(tools ...schemaDeliveryTestTool) SchemaRegistry {
products := map[string][]ToolSpec{}
for _, tool := range tools {
parts := strings.SplitN(tool.Canonical, ".", 2)
interfaceReason := "synthetic delivery fixture"
provenanceValues := map[string]any{
"canonical_path": tool.Canonical,
"effect": "",
"risk": "",
"confirmation": "",
"idempotency": "",
"interface_ref": nil,
"interface_mode": "local",
"availability": "available",
"interface_reason": interfaceReason,
"agent_summary": tool.Selection.AgentSummary,
}
for field, values := range map[string][]string{
"use_when": tool.Selection.UseWhen,
"avoid_when": tool.Selection.AvoidWhen,
"prerequisites": tool.Selection.Prerequisites,
"tips": tool.Selection.Tips,
"workflow_refs": tool.Selection.WorkflowRefs,
"examples": tool.Selection.Examples,
} {
if values != nil {
provenanceValues[field] = values
}
}
if tool.Selection.Reviewed != nil {
provenanceValues["reviewed"] = *tool.Selection.Reviewed
}
spec, err := ToolSpecFromRuntime(RuntimeToolSpecInput{
Identity: contract.ToolIdentitySpec{
ProductID: parts[0],
Name: parts[1],
CLIName: strings.Fields(tool.CLIPath)[len(strings.Fields(tool.CLIPath))-1],
CanonicalPath: tool.Canonical,
CLIPath: tool.CLIPath,
PrimaryCLIPath: tool.CLIPath,
Aliases: append([]string(nil), tool.Aliases...),
Source: "test",
},
Parameters: append([]ParameterSpec(nil), tool.Parameters...),
Interface: contract.InterfaceSpec{Mode: "local", Availability: "available", Reason: interfaceReason},
Selection: tool.Selection,
FieldProvenance: schemaDeliveryTestProvenance(provenanceValues),
})
if err != nil {
panic(err)
}
products[parts[0]] = append(products[parts[0]], spec)
}
productIDs := make([]string, 0, len(products))
for productID := range products {
productIDs = append(productIDs, productID)
}
sort.Strings(productIDs)
typedProducts := make([]ProductSpec, 0, len(productIDs))
for _, productID := range productIDs {
typedProducts = append(typedProducts, ProductSpec{ID: productID, Tools: products[productID]})
}
registry, err := SchemaRegistryFromRuntime("", typedProducts)
if err != nil {
panic(err)
}
return registry
}
func schemaDeliveryTestProvenance(fields map[string]any) map[string]contract.FieldProvenance {
provenance := make(map[string]contract.FieldProvenance, len(fields))
for field, value := range fields {
encoded, err := json.Marshal(value)
if err != nil {
panic(err)
}
selected := true
provenance[field] = contract.FieldProvenance{
Value: encoded,
Source: "test",
Precedence: "test",
Resolution: "test",
Candidates: []contract.FieldCandidateProvenance{{Value: append(json.RawMessage(nil), encoded...), Source: "test", Precedence: "test", Selected: &selected}},
}
}
return provenance
}