Files
玉澜andCursor 6c15b591a3 chore(schema): converge Embedded/Hints/provenance naming debt
Rename misleading public Embedded* loaders to Reviewed/Load APIs, keep
fail-closed HintsDir/-hints valves, and centralize wire provenance
string literals behind named consts without changing Catalog values.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-02 14:11:23 +08:00

2940 lines
108 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright 2026 Alibaba Group
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package agentmetadata
import (
"bufio"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io/fs"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli"
)
const CurrentVersion = 1
type File struct {
Version int `json:"version"`
SourceHash string `json:"source_hash"`
SurfaceHash string `json:"surface_hash,omitempty"`
Coverage Coverage `json:"coverage"`
Products map[string]ProductMetadata `json:"products"`
Tools map[string]ToolMetadata `json:"tools"`
}
type Coverage struct {
SurfaceProducts int `json:"surface_products,omitempty"`
ProductsWithMetadata int `json:"products_with_metadata"`
SurfaceTools int `json:"surface_tools,omitempty"`
ToolsWithMetadata int `json:"tools_with_metadata"`
ToolsWithSummary int `json:"tools_with_agent_summary,omitempty"`
ToolsWithUseWhen int `json:"tools_with_use_when,omitempty"`
ToolsWithAvoidWhen int `json:"tools_with_avoid_when,omitempty"`
ToolsWithExamples int `json:"tools_with_examples,omitempty"`
ToolsWithInterfaceMode int `json:"tools_with_interface_mode,omitempty"`
UnmatchedSkillTools int `json:"unmatched_skill_tools,omitempty"`
UnreviewedSkillTools int `json:"unreviewed_skill_tools,omitempty"`
}
type ProductMetadata struct {
AgentSummary string `json:"agent_summary,omitempty"`
AgentSummarySource string `json:"agent_summary_source,omitempty"`
UseWhen []string `json:"use_when,omitempty"`
AvoidWhen []string `json:"avoid_when,omitempty"`
SourceRefs []string `json:"source_refs,omitempty"`
FieldProvenance map[string]FieldProvenance `json:"field_provenance,omitempty"`
agentSummaryPresent bool
agentSummaryRank int
agentSummaryOrigin string
useWhenRank int
useWhenOrigin string
useWhenPresent bool
avoidWhenRank int
avoidWhenOrigin string
avoidWhenPresent bool
fieldCandidates map[string][]FieldCandidateProvenance
}
// MarshalJSON preserves the distinction between an omitted authored list and
// an explicitly authored empty list. The latter is a real precedence value: it
// intentionally clears a lower-ranked non-empty list and must be emitted as
// [] rather than being removed by omitempty.
func (metadata ProductMetadata) MarshalJSON() ([]byte, error) {
type wire ProductMetadata
encoded, err := json.Marshal(wire(metadata))
if err != nil {
return nil, err
}
var object map[string]json.RawMessage
_ = json.Unmarshal(encoded, &object)
for _, list := range []struct {
name string
value []string
present bool
}{
{"use_when", metadata.UseWhen, metadata.useWhenPresent},
{"avoid_when", metadata.AvoidWhen, metadata.avoidWhenPresent},
} {
if !listIsPresent(list.value, list.present) {
continue
}
value, _ := json.Marshal(normalizeAuthoredStrings(list.value))
object[list.name] = value
}
return json.Marshal(object)
}
// InterfaceRef links a stable public command to the MCP operation that
// implements it. It is interface identity, not runtime endpoint discovery.
type InterfaceRef struct {
ProductID string `json:"product_id"`
RPCName string `json:"rpc_name"`
}
// FieldProvenance identifies the winning source and the deterministic rule
// used to resolve one final Agent-facing field.
type FieldProvenance struct {
Value any `json:"value"`
Source string `json:"source"`
Precedence string `json:"precedence"`
Resolution string `json:"resolution"`
ReviewReason string `json:"review_reason,omitempty"`
Candidates []FieldCandidateProvenance `json:"candidates"`
OverriddenCandidates []FieldCandidateProvenance `json:"overridden_candidates,omitempty"`
}
// FieldCandidateProvenance preserves a non-winning input so precedence
// decisions remain auditable in the generated Agent contract.
type FieldCandidateProvenance struct {
Value any `json:"value"`
Source string `json:"source"`
Precedence string `json:"precedence"`
Selected bool `json:"selected"`
ReviewReason string `json:"review_reason,omitempty"`
}
type ToolMetadata struct {
AgentSummary string `json:"agent_summary,omitempty"`
AgentSummarySource string `json:"agent_summary_source,omitempty"`
UseWhen []string `json:"use_when,omitempty"`
AvoidWhen []string `json:"avoid_when,omitempty"`
Prerequisites []string `json:"prerequisites,omitempty"`
Tips []string `json:"tips,omitempty"`
Effect string `json:"effect,omitempty"`
EffectSource string `json:"effect_source,omitempty"`
Risk string `json:"risk,omitempty"`
Confirmation string `json:"confirmation,omitempty"`
Idempotency string `json:"idempotency,omitempty"`
WorkflowRefs []string `json:"workflow_refs,omitempty"`
Examples []string `json:"examples,omitempty"`
Reviewed *bool `json:"reviewed,omitempty"`
SourceRefs []string `json:"source_refs,omitempty"`
InterfaceRef *InterfaceRef `json:"interface_ref,omitempty"`
InterfaceMode string `json:"interface_mode,omitempty"`
Availability string `json:"availability,omitempty"`
InterfaceReason string `json:"interface_reason,omitempty"`
FieldProvenance map[string]FieldProvenance `json:"field_provenance,omitempty"`
agentSummaryPresent bool
agentSummaryRank int
agentSummaryOrigin string
useWhenRank int
useWhenOrigin string
useWhenPresent bool
avoidWhenRank int
avoidWhenOrigin string
avoidWhenPresent bool
prerequisitesRank int
prerequisitesOrigin string
prerequisitesPresent bool
tipsRank int
tipsOrigin string
tipsPresent bool
workflowRefsRank int
workflowRefsOrigin string
workflowRefsPresent bool
examplesRank int
examplesOrigin string
examplesPresent bool
effectPresent bool
riskPresent bool
confirmationPresent bool
idempotencyPresent bool
idempotencyRank int
idempotencyOrigin string
reviewedRank int
reviewedOrigin string
interfaceRefPresent bool
interfaceRefRank int
interfaceRefOrigin string
interfaceModePresent bool
interfaceModeRank int
interfaceModeOrigin string
availabilityPresent bool
availabilityRank int
availabilityOrigin string
interfaceReasonPresent bool
interfaceReasonRank int
interfaceReasonOrigin string
effectRank int
effectOrigin string
riskRank int
riskOrigin string
confirmationRank int
confirmationOrigin string
fieldCandidates map[string][]FieldCandidateProvenance
}
// MarshalJSON preserves explicit empty authored lists for the same reason as
// ProductMetadata.MarshalJSON. Unset lists remain omitted.
func (metadata ToolMetadata) MarshalJSON() ([]byte, error) {
type wire ToolMetadata
encoded, err := json.Marshal(wire(metadata))
if err != nil {
return nil, err
}
var object map[string]json.RawMessage
_ = json.Unmarshal(encoded, &object)
for _, list := range []struct {
name string
value []string
present bool
}{
{"use_when", metadata.UseWhen, metadata.useWhenPresent},
{"avoid_when", metadata.AvoidWhen, metadata.avoidWhenPresent},
{"prerequisites", metadata.Prerequisites, metadata.prerequisitesPresent},
{"tips", metadata.Tips, metadata.tipsPresent},
{"workflow_refs", metadata.WorkflowRefs, metadata.workflowRefsPresent},
{"examples", metadata.Examples, metadata.examplesPresent},
} {
if !listIsPresent(list.value, list.present) {
continue
}
value, _ := json.Marshal(normalizeAuthoredStrings(list.value))
object[list.name] = value
}
return json.Marshal(object)
}
const (
// Scalar fields use one source-only precedence for selection, safety, and
// interface disposition. Values never influence precedence: a reviewed
// explicit hint may intentionally upgrade or downgrade any scalar.
selectionRankDefault = 0
selectionRankMCPFallback = 10
selectionRankSkill = 100
selectionRankUnreviewedExplicit = 150
selectionRankImported = 200
selectionRankExplicit = 300
selectionRankReviewedExplicit = 400
selectionRankReviewedManual = 500
// Contract final declarations (corecmd.ContractDecl, registered in-process)
// outrank every file/manual source: the declaration in reviewed code is
// the final data source for declared tools.
selectionRankContractFinal = 600
selectionPrecedenceDefault = "inference_or_default"
selectionPrecedenceMCPFallback = "mcp_fallback"
selectionPrecedenceSkill = "skill"
selectionPrecedenceUnreviewedExplicit = "unreviewed_explicit"
selectionPrecedenceImported = "imported"
selectionPrecedenceExplicit = "explicit"
selectionPrecedenceReviewedExplicit = "reviewed_explicit"
selectionPrecedenceReviewedManual = cli.ProvenanceReviewedManual
selectionPrecedenceContractFinal = "contract_final"
)
// contractFinalOrigin labels every candidate sourced from an in-process
// Contract final declaration. It is not a file path; the declaration lives in
// reviewed command source code (corecmd.ContractDecl).
const contractFinalOrigin = "corecmd.contract"
type Options struct {
Root string
SkillPath string
ProductsDir string
IntentGuidePath string
// HintsDir is a fail-closed anti-regression valve. The field name and the
// "schema_hints/" error text are intentional: policy and callers still probe
// this retired path. Non-empty values must keep failing; do not rename away.
HintsDir string
// ManualHintsPath is a fail-closed anti-regression valve for the retired
// manual-hints file path. Keep the field name; non-empty values must fail.
ManualHintsPath string
InterfaceMetadataPath string
MaxExamples int
MaxInterfaceSummaryRunes int
ToolPaths map[string]string
CanonicalToolPaths map[string]string
BoundCommands cli.BoundCommandRegistry
ProductIDs map[string]bool
SurfaceHash string
SurfaceToolCount int
}
type Stats struct {
SourceFiles int
Products int
Tools int
ToolIntents int
Examples int
RiskRules int
InterfaceMetadata *InterfaceMetadataAudit
UnmatchedTools int
SourceProducts []string
SkillProductsOutsideSurface []string
SurfaceProductsWithoutRouting []string
UnmatchedReferences []UnmatchedReference
referenceReviews map[string]ReferenceReview
unreviewedSkillTools int
}
// UnmatchedReference identifies one Skill command reference that cannot be
// resolved against the versioned command surface. It is emitted only in the
// build-time audit and is not embedded in the runtime Agent schema.
type UnmatchedReference struct {
ToolPath string `json:"tool_path"`
Source string `json:"source,omitempty"`
Line int `json:"line,omitempty"`
Candidates []string `json:"candidates,omitempty"`
Review *ReferenceReview `json:"review,omitempty"`
}
// ReferenceReview is an optional disposition of a Skill command reference that
// is not a current public leaf. Production no longer loads reviewed HintFile
// reference_review maps; unmatched Skill paths are recorded in the build-time
// audit without requiring a reviewed disposition.
type ReferenceReview struct {
Status string `json:"status"`
Target string `json:"target,omitempty"`
Reason string `json:"reason"`
}
// Audit contains build-time diagnostics that are intentionally kept separate
// from the runtime Agent metadata contract.
type Audit struct {
Version int `json:"version"`
SourceHash string `json:"source_hash"`
SurfaceHash string `json:"surface_hash,omitempty"`
SourceFiles int `json:"source_files"`
InterfaceMetadata *InterfaceMetadataAudit `json:"interface_metadata,omitempty"`
Coverage Coverage `json:"coverage"`
SourceProducts []string `json:"source_products,omitempty"`
SkillProductsOutsideSurface []string `json:"skill_products_outside_surface,omitempty"`
SurfaceProductsWithoutRouting []string `json:"surface_products_without_routing_metadata,omitempty"`
UnmatchedReferences []UnmatchedReference `json:"unmatched_references,omitempty"`
}
type sourceFile struct {
path string
display string
data []byte
}
type commandReference struct {
text string
line int
commentIntent string
}
type sourceLocation struct {
source string
line int
}
type sourceTracker map[string]map[string]sourceLocation
var (
quotedIntentRE = regexp.MustCompile(`用户(?:提到|说)["“]([^"”]+)["”]`)
codeSpanRE = regexp.MustCompile("`([^`]+)`")
stepCommentRE = regexp.MustCompile(`(?i)^step\s+[0-9]+\s*[::]\s*`)
)
func Generate(opts Options) (File, Stats, error) {
if len(opts.CanonicalToolPaths) == 0 || len(opts.ToolPaths) == 0 || len(opts.ProductIDs) == 0 {
return File{}, Stats{}, fmt.Errorf("complete Effective CommandRegistry projection is required")
}
if len(opts.BoundCommands.ByCanonical) != len(opts.CanonicalToolPaths) {
return File{}, Stats{}, fmt.Errorf("complete Cobra-bound CommandRegistry is required")
}
return generateFromSources(opts)
}
// generateFromSources retains the lower-precedence evidence parsers as a
// package-internal seam for focused tests. Production callers must use Generate.
// HintsDir and ManualHintsPath are retired: ProductDecl / ContractFinal own
// routing and leaf facts. Non-empty values fail closed in loadSources;
// Skill Markdown remains evidence-only.
func generateFromSources(opts Options) (File, Stats, error) {
if opts.Root == "" {
opts.Root = "."
}
if opts.MaxExamples <= 0 {
opts.MaxExamples = 2
}
files, err := loadSources(opts)
if err != nil {
return File{}, Stats{}, err
}
byDisplay := make(map[string]sourceFile, len(files))
for _, file := range files {
byDisplay[file.display] = file
}
out := File{
Version: CurrentVersion,
SourceHash: hashSources(files),
SurfaceHash: strings.TrimSpace(opts.SurfaceHash),
Products: map[string]ProductMetadata{},
Tools: map[string]ToolMetadata{},
}
stats := Stats{SourceFiles: len(files), referenceReviews: map[string]ReferenceReview{}}
origins := sourceTracker{}
skillDisplay := displayPath(opts.Root, resolvePath(opts.Root, opts.SkillPath))
if skill, ok := byDisplay[skillDisplay]; ok {
parseProductRouting(&out, string(skill.data), skill.display)
if err := parseDangerRules(&out, string(skill.data), skill.display, &stats, origins); err != nil {
return File{}, Stats{}, err
}
}
intentDisplay := displayPath(opts.Root, resolvePath(opts.Root, opts.IntentGuidePath))
if guide, ok := byDisplay[intentDisplay]; ok {
parseIntentGuide(&out, string(guide.data), guide.display, origins)
}
productFiles := make([]sourceFile, 0)
productsRoot := filepath.Clean(resolvePath(opts.Root, opts.ProductsDir))
productsPrefix := productsRoot + string(filepath.Separator)
for _, file := range files {
if strings.HasPrefix(filepath.Clean(file.path), productsPrefix) {
productFiles = append(productFiles, file)
}
}
sort.Slice(productFiles, func(i, j int) bool { return productFiles[i].display < productFiles[j].display })
sourceProducts := map[string]bool{}
for _, file := range productFiles {
body := string(file.data)
references := collectCommandReferences(body)
productIDs := sourceProductIDs(file, productsRoot, references, opts.ProductIDs)
for _, productID := range productIDs {
sourceProducts[productID] = true
}
known := collectCommandPaths(productIDs, references)
parseToolIntents(&out, productIDs, known, body, file.display, origins)
if err := parseExamples(&out, known, references, file.display, opts.MaxExamples, origins); err != nil {
return File{}, Stats{}, err
}
}
if err := applyInterfaceMetadataFallback(&out, byDisplay, opts, &stats, origins); err != nil {
return File{}, Stats{}, err
}
normalizeFile(&out, opts.MaxExamples)
for productID := range out.Products {
sourceProducts[productID] = true
}
for toolPath := range out.Tools {
if productID := metadataProductID(toolPath); productID != "" {
sourceProducts[productID] = true
}
}
stats.SourceProducts = sortedBoolKeys(sourceProducts)
if len(opts.ProductIDs) > 0 {
for _, productID := range stats.SourceProducts {
if !opts.ProductIDs[productID] {
stats.SkillProductsOutsideSurface = append(stats.SkillProductsOutsideSurface, productID)
}
}
}
if err := reconcileSurface(&out, opts, &stats, origins); err != nil {
return File{}, Stats{}, err
}
if err := applyContractFinalDeclarations(&out, opts); err != nil {
return File{}, Stats{}, err
}
seedEffectiveToolProjection(&out, opts.ToolPaths)
if err := validateEffectiveToolProjection(out, opts); err != nil {
return File{}, Stats{}, err
}
normalizeFile(&out, opts.MaxExamples)
if err := validateToolFieldCandidateConflicts(out); err != nil {
return File{}, Stats{}, err
}
finalizeInterfaceDispositions(&out)
if err := validateInterfaceDispositions(out); err != nil {
return File{}, Stats{}, err
}
if len(opts.ProductIDs) > 0 {
for productID := range opts.ProductIDs {
if _, ok := out.Products[productID]; !ok {
stats.SurfaceProductsWithoutRouting = append(stats.SurfaceProductsWithoutRouting, productID)
}
}
sort.Strings(stats.SurfaceProductsWithoutRouting)
}
stats.Products = len(out.Products)
stats.Tools = len(out.Tools)
toolsWithSummary, toolsWithUseWhen, toolsWithAvoidWhen := 0, 0, 0
toolsWithExamples, toolsWithInterfaceMode := 0, 0
for _, metadata := range out.Tools {
stats.ToolIntents += len(metadata.UseWhen)
stats.Examples += len(metadata.Examples)
if strings.TrimSpace(metadata.AgentSummary) != "" {
toolsWithSummary++
}
// Coverage is about a resolved field, not truthiness. A reviewed [] is
// an authored winner that intentionally clears lower-priority guidance.
if listIsPresent(metadata.UseWhen, metadata.useWhenPresent) {
toolsWithUseWhen++
}
if listIsPresent(metadata.AvoidWhen, metadata.avoidWhenPresent) {
toolsWithAvoidWhen++
}
if listIsPresent(metadata.Examples, metadata.examplesPresent) {
toolsWithExamples++
}
if strings.TrimSpace(metadata.InterfaceMode) != "" {
toolsWithInterfaceMode++
}
}
out.Coverage = Coverage{
SurfaceProducts: len(opts.ProductIDs),
ProductsWithMetadata: len(out.Products),
SurfaceTools: opts.SurfaceToolCount,
ToolsWithMetadata: len(out.Tools),
ToolsWithSummary: toolsWithSummary,
ToolsWithUseWhen: toolsWithUseWhen,
ToolsWithAvoidWhen: toolsWithAvoidWhen,
ToolsWithExamples: toolsWithExamples,
ToolsWithInterfaceMode: toolsWithInterfaceMode,
UnmatchedSkillTools: stats.UnmatchedTools,
UnreviewedSkillTools: stats.unreviewedSkillTools,
}
return out, stats, nil
}
func BuildAudit(file File, stats Stats) Audit {
return Audit{
Version: CurrentVersion,
SourceHash: file.SourceHash,
SurfaceHash: file.SurfaceHash,
SourceFiles: stats.SourceFiles,
InterfaceMetadata: stats.InterfaceMetadata,
Coverage: file.Coverage,
SourceProducts: append([]string(nil), stats.SourceProducts...),
SkillProductsOutsideSurface: append([]string(nil), stats.SkillProductsOutsideSurface...),
SurfaceProductsWithoutRouting: append([]string(nil), stats.SurfaceProductsWithoutRouting...),
UnmatchedReferences: append([]UnmatchedReference(nil), stats.UnmatchedReferences...),
}
}
func reconcileSurface(file *File, opts Options, stats *Stats, origins sourceTracker) error {
if len(opts.ProductIDs) > 0 {
for productID := range file.Products {
if !opts.ProductIDs[productID] {
delete(file.Products, productID)
}
}
}
if len(opts.ToolPaths) == 0 {
return nil
}
reconciled := map[string]ToolMetadata{}
sourcePaths := make([]string, 0, len(file.Tools))
for skillPath := range file.Tools {
sourcePaths = append(sourcePaths, skillPath)
}
sort.Strings(sourcePaths)
for _, skillPath := range sourcePaths {
metadata := file.Tools[skillPath]
livePath, ok := opts.ToolPaths[skillPath]
if !ok {
review, reviewed := stats.referenceReviews[skillPath]
if reviewed && review.Status == "alias" {
if target, targetOK := opts.ToolPaths[normalizeCommandPath(review.Target)]; targetOK {
existing := reconciled[target]
merged, err := mergeToolMetadata(existing, metadata, target)
if err != nil {
return err
}
reconciled[target] = merged
continue
}
}
stats.UnmatchedTools++
if !reviewed {
stats.unreviewedSkillTools++
}
locations := origins.locations(skillPath)
if len(locations) == 0 {
locations = []sourceLocation{{}}
}
candidates := candidateToolPaths(skillPath, opts.ToolPaths, 3)
for _, location := range locations {
reference := UnmatchedReference{
ToolPath: skillPath,
Source: location.source,
Line: location.line,
Candidates: append([]string(nil), candidates...),
}
if reviewed {
value := review
reference.Review = &value
}
stats.UnmatchedReferences = append(stats.UnmatchedReferences, reference)
}
continue
}
existing := reconciled[livePath]
merged, err := mergeToolMetadata(existing, metadata, livePath)
if err != nil {
return err
}
reconciled[livePath] = merged
}
file.Tools = reconciled
sort.Slice(stats.UnmatchedReferences, func(i, j int) bool {
left, right := stats.UnmatchedReferences[i], stats.UnmatchedReferences[j]
if left.Source != right.Source {
return left.Source < right.Source
}
if left.Line != right.Line {
return left.Line < right.Line
}
return left.ToolPath < right.ToolPath
})
return nil
}
// seedEffectiveToolProjection materializes one Agent metadata record for every
// effective public command, including reviewed manual-only commands. Empty
// records remain subject to the normal defaulting and final release gates; the
// important identity invariant here is that absence can no longer be hidden
// behind a surface count.
func seedEffectiveToolProjection(file *File, toolPaths map[string]string) {
if file == nil {
return
}
if file.Tools == nil {
file.Tools = map[string]ToolMetadata{}
}
for _, rawPrimary := range toolPaths {
primary := normalizeCommandPath(rawPrimary)
if primary == "" {
continue
}
if _, exists := file.Tools[primary]; !exists {
file.Tools[primary] = ToolMetadata{}
}
}
}
// validateEffectiveToolProjection makes the EffectiveCommandRegistry
// projection fail closed. ToolPaths contains canonical paths and reviewed
// aliases mapped to their one primary CLI path; therefore its unique values
// are the exact public command set that Agent metadata must deliver.
func validateEffectiveToolProjection(file File, opts Options) error {
if len(opts.ToolPaths) == 0 {
return nil
}
expected := make(map[string]bool, len(opts.ToolPaths))
for _, rawPrimary := range opts.ToolPaths {
if primary := normalizeCommandPath(rawPrimary); primary != "" {
expected[primary] = true
}
}
missing := make([]string, 0)
for primary := range expected {
if _, ok := file.Tools[primary]; !ok {
missing = append(missing, primary)
}
}
unexpected := make([]string, 0)
for primary := range file.Tools {
if !expected[normalizeCommandPath(primary)] {
unexpected = append(unexpected, primary)
}
}
sort.Strings(missing)
sort.Strings(unexpected)
if len(missing) > 0 || len(unexpected) > 0 {
return fmt.Errorf(
"agent metadata does not exactly project the effective CommandRegistry: missing=%v unexpected=%v",
missing,
unexpected,
)
}
if opts.SurfaceToolCount > 0 && opts.SurfaceToolCount != len(expected) {
return fmt.Errorf(
"agent metadata effective CommandRegistry count %d disagrees with unique projected tools %d",
opts.SurfaceToolCount,
len(expected),
)
}
return nil
}
func mergeToolMetadata(left, right ToolMetadata, path string) (ToolMetadata, error) {
seedToolFieldCandidates(&left)
seedToolFieldCandidates(&right)
mergeFieldCandidateHistory(&left, right)
previousSummaryPresent := scalarIsPresent(left.AgentSummary, left.agentSummaryPresent)
previousSummaryRank := left.agentSummaryRank
previousSummaryOrigin := left.agentSummaryOrigin
incomingSummaryPresent := scalarIsPresent(right.AgentSummary, right.agentSummaryPresent)
incomingSummaryRank := effectiveSelectionScalarRank(right.AgentSummary, incomingSummaryPresent, right.agentSummaryRank)
incomingSummaryOrigin := firstNonEmpty(right.agentSummaryOrigin, right.AgentSummarySource)
recordStringFieldCandidate(&left, "agent_summary", right.AgentSummary, incomingSummaryPresent, incomingSummaryRank, incomingSummaryOrigin,
fieldWinnerReviewReason(right, "agent_summary", right.AgentSummary, incomingSummaryOrigin, incomingSummaryRank))
if err := mergeRankedStringValue(
&left.AgentSummary, &left.agentSummaryPresent, &left.agentSummaryRank, &left.agentSummaryOrigin,
right.AgentSummary, incomingSummaryPresent, incomingSummaryRank, incomingSummaryOrigin, path, "agent_summary",
); err != nil {
return ToolMetadata{}, err
}
incomingSummaryWon := incomingSummaryPresent &&
(!previousSummaryPresent || incomingSummaryRank > previousSummaryRank ||
(incomingSummaryRank == previousSummaryRank && left.agentSummaryOrigin != previousSummaryOrigin && left.agentSummaryOrigin == strings.TrimSpace(incomingSummaryOrigin)))
if incomingSummaryWon {
left.AgentSummarySource = right.AgentSummarySource
}
for _, list := range []struct {
name string
leftValue *[]string
leftPresent *bool
leftRank *int
leftOrigin *string
rightValue []string
rightPresent bool
rightRank int
rightOrigin string
}{
{"use_when", &left.UseWhen, &left.useWhenPresent, &left.useWhenRank, &left.useWhenOrigin, right.UseWhen, listIsPresent(right.UseWhen, right.useWhenPresent), right.useWhenRank, right.useWhenOrigin},
{"avoid_when", &left.AvoidWhen, &left.avoidWhenPresent, &left.avoidWhenRank, &left.avoidWhenOrigin, right.AvoidWhen, listIsPresent(right.AvoidWhen, right.avoidWhenPresent), right.avoidWhenRank, right.avoidWhenOrigin},
{"prerequisites", &left.Prerequisites, &left.prerequisitesPresent, &left.prerequisitesRank, &left.prerequisitesOrigin, right.Prerequisites, listIsPresent(right.Prerequisites, right.prerequisitesPresent), right.prerequisitesRank, right.prerequisitesOrigin},
{"tips", &left.Tips, &left.tipsPresent, &left.tipsRank, &left.tipsOrigin, right.Tips, listIsPresent(right.Tips, right.tipsPresent), right.tipsRank, right.tipsOrigin},
{"workflow_refs", &left.WorkflowRefs, &left.workflowRefsPresent, &left.workflowRefsRank, &left.workflowRefsOrigin, right.WorkflowRefs, listIsPresent(right.WorkflowRefs, right.workflowRefsPresent), right.workflowRefsRank, right.workflowRefsOrigin},
{"examples", &left.Examples, &left.examplesPresent, &left.examplesRank, &left.examplesOrigin, right.Examples, listIsPresent(right.Examples, right.examplesPresent), right.examplesRank, right.examplesOrigin},
} {
incomingRank := effectiveSelectionListRank(list.rightValue, list.rightPresent, list.rightRank)
if err := mergeRankedStringList(list.leftValue, list.leftPresent, list.leftRank, list.leftOrigin, list.rightValue, list.rightPresent, incomingRank, list.rightOrigin, path, list.name); err != nil {
return ToolMetadata{}, err
}
}
left.SourceRefs = append(left.SourceRefs, right.SourceRefs...)
if err := mergeEffectValue(&left, right.Effect, scalarIsPresent(right.Effect, right.effectPresent), right.EffectSource, right.effectRank, right.effectOrigin,
fieldWinnerReviewReason(right, "effect", right.Effect, right.effectOrigin, right.effectRank), path); err != nil {
return ToolMetadata{}, err
}
if err := mergeRiskValue(&left, right.Risk, scalarIsPresent(right.Risk, right.riskPresent), right.riskRank, right.riskOrigin,
fieldWinnerReviewReason(right, "risk", right.Risk, right.riskOrigin, right.riskRank), path); err != nil {
return ToolMetadata{}, err
}
if err := mergeConfirmationValue(&left, right.Confirmation, scalarIsPresent(right.Confirmation, right.confirmationPresent), right.confirmationRank, right.confirmationOrigin,
fieldWinnerReviewReason(right, "confirmation", right.Confirmation, right.confirmationOrigin, right.confirmationRank), path); err != nil {
return ToolMetadata{}, err
}
idempotencyPresent := scalarIsPresent(right.Idempotency, right.idempotencyPresent)
recordStringFieldCandidate(&left, "idempotency", right.Idempotency, idempotencyPresent, right.idempotencyRank, right.idempotencyOrigin,
fieldWinnerReviewReason(right, "idempotency", right.Idempotency, right.idempotencyOrigin, right.idempotencyRank))
if err := mergeRankedStringValue(
&left.Idempotency, &left.idempotencyPresent, &left.idempotencyRank, &left.idempotencyOrigin,
right.Idempotency, idempotencyPresent, right.idempotencyRank, right.idempotencyOrigin, path, "idempotency",
); err != nil {
return ToolMetadata{}, err
}
if right.Reviewed != nil {
recordTypedFieldCandidateValue(&left, "reviewed", *right.Reviewed, true, right.reviewedRank, right.reviewedOrigin,
fieldWinnerReviewReasonValue(right, "reviewed", *right.Reviewed, right.reviewedOrigin, right.reviewedRank))
if left.Reviewed == nil || right.reviewedRank > left.reviewedRank {
value := *right.Reviewed
left.Reviewed = &value
left.reviewedRank = right.reviewedRank
left.reviewedOrigin = right.reviewedOrigin
} else if right.reviewedRank == left.reviewedRank && *left.Reviewed == *right.Reviewed {
left.reviewedOrigin = stableSource(left.reviewedOrigin, right.reviewedOrigin)
}
}
if err := mergeRankedInterfaceRef(&left, right, path); err != nil {
return ToolMetadata{}, err
}
for _, field := range []struct {
name string
leftValue *string
leftPresent *bool
leftRank *int
leftOrigin *string
rightValue string
rightPresent bool
rightRank int
rightOrigin string
}{
{"interface_mode", &left.InterfaceMode, &left.interfaceModePresent, &left.interfaceModeRank, &left.interfaceModeOrigin, right.InterfaceMode, scalarIsPresent(right.InterfaceMode, right.interfaceModePresent), right.interfaceModeRank, right.interfaceModeOrigin},
{"availability", &left.Availability, &left.availabilityPresent, &left.availabilityRank, &left.availabilityOrigin, right.Availability, scalarIsPresent(right.Availability, right.availabilityPresent), right.availabilityRank, right.availabilityOrigin},
{"interface_reason", &left.InterfaceReason, &left.interfaceReasonPresent, &left.interfaceReasonRank, &left.interfaceReasonOrigin, right.InterfaceReason, scalarIsPresent(right.InterfaceReason, right.interfaceReasonPresent), right.interfaceReasonRank, right.interfaceReasonOrigin},
} {
rank := effectiveSelectionScalarRank(field.rightValue, field.rightPresent, field.rightRank)
recordStringFieldCandidate(&left, field.name, field.rightValue, field.rightPresent, rank, field.rightOrigin,
fieldWinnerReviewReason(right, field.name, field.rightValue, field.rightOrigin, rank))
if err := mergeRankedStringValue(
field.leftValue, field.leftPresent, field.leftRank, field.leftOrigin,
field.rightValue, field.rightPresent, rank, field.rightOrigin,
path, field.name,
); err != nil {
return ToolMetadata{}, err
}
}
left.UseWhen = normalizeAuthoredStrings(left.UseWhen)
left.AvoidWhen = normalizeAuthoredStrings(left.AvoidWhen)
left.Prerequisites = normalizeAuthoredStrings(left.Prerequisites)
left.Tips = normalizeAuthoredStrings(left.Tips)
left.WorkflowRefs = normalizeAuthoredStrings(left.WorkflowRefs)
left.Examples = normalizeAuthoredStrings(left.Examples)
preserveExplicitEmptyToolLists(&left)
left.SourceRefs = normalizedStrings(left.SourceRefs)
syncToolFieldProvenance(&left)
return left, nil
}
func seedToolFieldCandidates(metadata *ToolMetadata) {
if metadata == nil {
return
}
recordStringFieldCandidate(metadata, "agent_summary", metadata.AgentSummary, scalarIsPresent(metadata.AgentSummary, metadata.agentSummaryPresent), effectiveSelectionScalarRank(metadata.AgentSummary, metadata.agentSummaryPresent, metadata.agentSummaryRank), firstNonEmpty(metadata.agentSummaryOrigin, metadata.AgentSummarySource), "")
recordStringFieldCandidate(metadata, "effect", metadata.Effect, scalarIsPresent(metadata.Effect, metadata.effectPresent), metadata.effectRank, firstNonEmpty(metadata.effectOrigin, metadata.EffectSource), "")
recordStringFieldCandidate(metadata, "risk", metadata.Risk, scalarIsPresent(metadata.Risk, metadata.riskPresent), metadata.riskRank, metadata.riskOrigin, "")
recordStringFieldCandidate(metadata, "confirmation", metadata.Confirmation, scalarIsPresent(metadata.Confirmation, metadata.confirmationPresent), metadata.confirmationRank, metadata.confirmationOrigin, "")
recordStringFieldCandidate(metadata, "idempotency", metadata.Idempotency, scalarIsPresent(metadata.Idempotency, metadata.idempotencyPresent), metadata.idempotencyRank, metadata.idempotencyOrigin, "")
if metadata.InterfaceRef != nil || metadata.interfaceRefPresent {
rank := metadata.interfaceRefRank
if rank == selectionRankDefault {
rank = selectionRankSkill
}
var value any
if metadata.InterfaceRef != nil {
value = metadata.InterfaceRef.ProductID + "." + metadata.InterfaceRef.RPCName
}
recordTypedFieldCandidateValue(metadata, "interface_ref", value, true, rank, metadata.interfaceRefOrigin, "")
}
recordStringFieldCandidate(metadata, "interface_mode", metadata.InterfaceMode, scalarIsPresent(metadata.InterfaceMode, metadata.interfaceModePresent), effectiveSelectionScalarRank(metadata.InterfaceMode, metadata.interfaceModePresent, metadata.interfaceModeRank), metadata.interfaceModeOrigin, "")
recordStringFieldCandidate(metadata, "availability", metadata.Availability, scalarIsPresent(metadata.Availability, metadata.availabilityPresent), effectiveSelectionScalarRank(metadata.Availability, metadata.availabilityPresent, metadata.availabilityRank), metadata.availabilityOrigin, "")
recordStringFieldCandidate(metadata, "interface_reason", metadata.InterfaceReason, scalarIsPresent(metadata.InterfaceReason, metadata.interfaceReasonPresent), effectiveSelectionScalarRank(metadata.InterfaceReason, metadata.interfaceReasonPresent, metadata.interfaceReasonRank), metadata.interfaceReasonOrigin, "")
if metadata.Reviewed != nil {
recordTypedFieldCandidateValue(metadata, "reviewed", *metadata.Reviewed, true, metadata.reviewedRank, metadata.reviewedOrigin, "")
}
for _, list := range []struct {
name string
value []string
present bool
rank int
origin string
}{
{"use_when", metadata.UseWhen, listIsPresent(metadata.UseWhen, metadata.useWhenPresent), metadata.useWhenRank, metadata.useWhenOrigin},
{"avoid_when", metadata.AvoidWhen, listIsPresent(metadata.AvoidWhen, metadata.avoidWhenPresent), metadata.avoidWhenRank, metadata.avoidWhenOrigin},
{"prerequisites", metadata.Prerequisites, listIsPresent(metadata.Prerequisites, metadata.prerequisitesPresent), metadata.prerequisitesRank, metadata.prerequisitesOrigin},
{"tips", metadata.Tips, listIsPresent(metadata.Tips, metadata.tipsPresent), metadata.tipsRank, metadata.tipsOrigin},
{"workflow_refs", metadata.WorkflowRefs, listIsPresent(metadata.WorkflowRefs, metadata.workflowRefsPresent), metadata.workflowRefsRank, metadata.workflowRefsOrigin},
{"examples", metadata.Examples, listIsPresent(metadata.Examples, metadata.examplesPresent), metadata.examplesRank, metadata.examplesOrigin},
} {
recordListFieldCandidate(metadata, list.name, list.value, list.present, effectiveSelectionListRank(list.value, list.present, list.rank), list.origin, "")
}
}
func mergeRankedString(target *string, targetRank *int, targetOrigin *string, incoming string, incomingRank int, incomingOrigin, path, field string) error {
return mergeRankedStringValue(
target, nil, targetRank, targetOrigin,
incoming, strings.TrimSpace(incoming) != "", incomingRank, incomingOrigin, path, field,
)
}
// mergeRankedStringValue keeps authored presence separate from the string
// value. An explicit "" is therefore a real candidate which can clear a
// lower-ranked non-empty value. Callers that do not expose authored presence
// continue to use mergeRankedString, where an empty string means absence.
func mergeRankedStringValue(target *string, targetPresent *bool, targetRank *int, targetOrigin *string, incoming string, incomingPresent bool, incomingRank int, incomingOrigin, path, field string) error {
if !incomingPresent {
return nil
}
incoming = strings.TrimSpace(incoming)
incomingOrigin = strings.TrimSpace(incomingOrigin)
current := strings.TrimSpace(*target)
currentPresent := current != ""
if targetPresent != nil {
currentPresent = currentPresent || *targetPresent
}
if !currentPresent || incomingRank > *targetRank {
*target = incoming
if targetPresent != nil {
*targetPresent = true
}
*targetRank = incomingRank
*targetOrigin = incomingOrigin
return nil
}
if incomingRank < *targetRank {
return nil
}
if current != incoming {
return fmt.Errorf("agent metadata conflict for %s field %s at precedence %d: %q from %s conflicts with %q from %s",
path, field, incomingRank, *target, firstNonEmpty(*targetOrigin, "<unknown>"), incoming, firstNonEmpty(incomingOrigin, "<unknown>"))
}
if targetPresent != nil {
*targetPresent = true
}
*targetOrigin = stableSource(*targetOrigin, incomingOrigin)
return nil
}
func mergeRankedStringList(target *[]string, targetPresent *bool, targetRank *int, targetOrigin *string, incoming []string, incomingPresent bool, incomingRank int, incomingOrigin, path, field string) error {
if !incomingPresent {
return nil
}
incoming = normalizeAuthoredStrings(incoming)
incomingOrigin = strings.TrimSpace(incomingOrigin)
current := normalizeAuthoredStrings(*target)
currentPresent := listIsPresent(*target, *targetPresent)
if !currentPresent || incomingRank > *targetRank {
*target = cloneStringList(incoming)
*targetPresent = true
*targetRank = incomingRank
*targetOrigin = incomingOrigin
return nil
}
if incomingRank < *targetRank {
return nil
}
if incomingRank == selectionRankSkill {
*target = normalizeAuthoredStrings(append(current, incoming...))
*targetPresent = true
*targetOrigin = combinedSkillSource(*targetOrigin, incomingOrigin)
return nil
}
if !fieldValueEqual(current, incoming) {
return fmt.Errorf("agent metadata conflict for %s field %s at precedence %d: %s from %s conflicts with %s from %s",
path, field, incomingRank,
fieldValueDisplay(current), firstNonEmpty(*targetOrigin, "<unknown>"),
fieldValueDisplay(incoming), firstNonEmpty(incomingOrigin, "<unknown>"))
}
*target = cloneStringList(current)
*targetPresent = true
*targetOrigin = stableSource(*targetOrigin, incomingOrigin)
return nil
}
func effectiveSelectionRank(value string, rank int) int {
return effectiveSelectionScalarRank(value, strings.TrimSpace(value) != "", rank)
}
func effectiveSelectionScalarRank(value string, present bool, rank int) int {
if scalarIsPresent(value, present) && rank == selectionRankDefault {
return selectionRankSkill
}
return rank
}
func scalarIsPresent(value string, explicit bool) bool {
return explicit || strings.TrimSpace(value) != ""
}
func effectiveSelectionListRank(values []string, present bool, rank int) int {
if listIsPresent(values, present) && rank == selectionRankDefault {
return selectionRankSkill
}
return rank
}
func mergeRankedInterfaceRef(left *ToolMetadata, right ToolMetadata, path string) error {
if left == nil || (right.InterfaceRef == nil && !right.interfaceRefPresent) {
return nil
}
rank := right.interfaceRefRank
if rank == selectionRankDefault {
rank = selectionRankSkill
}
rightValue := interfaceRefCandidateValue(right.InterfaceRef)
recordTypedFieldCandidateValue(left, "interface_ref", rightValue, true, rank, right.interfaceRefOrigin,
fieldWinnerReviewReasonValue(right, "interface_ref", rightValue, right.interfaceRefOrigin, rank))
leftPresent := left.InterfaceRef != nil || left.interfaceRefPresent
if !leftPresent || rank > left.interfaceRefRank {
left.InterfaceRef = cloneInterfaceRef(right.InterfaceRef)
left.interfaceRefPresent = true
left.interfaceRefRank = rank
left.interfaceRefOrigin = right.interfaceRefOrigin
return nil
}
if rank < left.interfaceRefRank {
return nil
}
leftValue := interfaceRefCandidateValue(left.InterfaceRef)
if !fieldValueEqual(leftValue, rightValue) {
return fmt.Errorf("agent metadata conflict for %s field interface_ref at precedence %d: %s from %s conflicts with %s from %s",
path, rank,
fieldValueDisplay(leftValue), firstNonEmpty(left.interfaceRefOrigin, "<unknown>"),
fieldValueDisplay(rightValue), firstNonEmpty(right.interfaceRefOrigin, "<unknown>"))
}
left.interfaceRefPresent = true
left.interfaceRefOrigin = stableSource(left.interfaceRefOrigin, right.interfaceRefOrigin)
return nil
}
func interfaceRefCandidateValue(ref *InterfaceRef) any {
if ref == nil {
return nil
}
return strings.TrimSpace(ref.ProductID) + "." + strings.TrimSpace(ref.RPCName)
}
func cloneInterfaceRef(ref *InterfaceRef) *InterfaceRef {
if ref == nil {
return nil
}
value := *ref
return &value
}
func firstNonEmpty(values ...string) string {
for _, value := range values {
if value = strings.TrimSpace(value); value != "" {
return value
}
}
return ""
}
func stableSource(left, right string) string {
left = strings.TrimSpace(left)
right = strings.TrimSpace(right)
if left == "" || (right != "" && right < left) {
return right
}
return left
}
func listIsPresent(values []string, explicit bool) bool {
return explicit || values != nil
}
func cloneStringList(values []string) []string {
if values == nil {
return nil
}
return append([]string{}, values...)
}
func preserveExplicitEmptyToolLists(metadata *ToolMetadata) {
if metadata == nil {
return
}
for _, list := range []struct {
value *[]string
present bool
}{
{&metadata.UseWhen, metadata.useWhenPresent},
{&metadata.AvoidWhen, metadata.avoidWhenPresent},
{&metadata.Prerequisites, metadata.prerequisitesPresent},
{&metadata.Tips, metadata.tipsPresent},
{&metadata.WorkflowRefs, metadata.workflowRefsPresent},
{&metadata.Examples, metadata.examplesPresent},
} {
if list.present && *list.value == nil {
*list.value = []string{}
}
}
}
func preserveExplicitEmptyProductLists(metadata *ProductMetadata) {
if metadata == nil {
return
}
if metadata.useWhenPresent && metadata.UseWhen == nil {
metadata.UseWhen = []string{}
}
if metadata.avoidWhenPresent && metadata.AvoidWhen == nil {
metadata.AvoidWhen = []string{}
}
}
func cloneFieldValue(value any) any {
switch typed := value.(type) {
case []string:
return cloneStringList(typed)
default:
return typed
}
}
func fieldValueKey(value any) string {
encoded, err := json.Marshal(value)
if err != nil {
return fmt.Sprintf("%v", value)
}
return string(encoded)
}
func fieldValueDisplay(value any) string {
return fieldValueKey(value)
}
func fieldStringValue(value any) string {
text, _ := value.(string)
return strings.TrimSpace(text)
}
func fieldValueEqual(left, right any) bool {
return fieldValueKey(left) == fieldValueKey(right)
}
func fieldCandidateEqual(left, right FieldCandidateProvenance) bool {
return fieldValueEqual(left.Value, right.Value) &&
left.Source == right.Source &&
left.Precedence == right.Precedence &&
left.Selected == right.Selected &&
left.ReviewReason == right.ReviewReason
}
func normalizeListFieldCandidates(metadata *ToolMetadata, maxExamples int) {
if metadata == nil {
return
}
for field, candidates := range metadata.fieldCandidates {
for index := range candidates {
values, ok := candidates[index].Value.([]string)
if !ok {
continue
}
values = normalizeAuthoredStrings(values)
if field == "examples" && maxExamples > 0 && len(values) > maxExamples {
values = values[:maxExamples]
}
candidates[index].Value = cloneStringList(values)
}
metadata.fieldCandidates[field] = candidates
}
}
func mergeEffect(metadata *ToolMetadata, incoming, effectSource string, rank int, origin, reviewReason, path string) error {
return mergeEffectValue(metadata, incoming, strings.TrimSpace(incoming) != "", effectSource, rank, origin, reviewReason, path)
}
func mergeEffectValue(metadata *ToolMetadata, incoming string, incomingPresent bool, effectSource string, rank int, origin, reviewReason, path string) error {
if metadata == nil || !incomingPresent {
return nil
}
previousValue := strings.TrimSpace(metadata.Effect)
previousPresent := scalarIsPresent(metadata.Effect, metadata.effectPresent)
previousRank := metadata.effectRank
previousOrigin := metadata.effectOrigin
recordStringFieldCandidate(metadata, "effect", incoming, true, rank, origin, reviewReason)
if err := mergeRankedStringValue(
&metadata.Effect, &metadata.effectPresent, &metadata.effectRank, &metadata.effectOrigin,
incoming, true, rank, origin, path, "effect",
); err != nil {
return err
}
if scalarIncomingWon(previousValue, previousPresent, previousRank, previousOrigin, incoming, true, rank, origin, metadata.effectOrigin) {
metadata.EffectSource = strings.TrimSpace(effectSource)
}
return nil
}
func mergeRisk(metadata *ToolMetadata, incoming string, rank int, origin, reviewReason, path string) error {
return mergeRiskValue(metadata, incoming, strings.TrimSpace(incoming) != "", rank, origin, reviewReason, path)
}
func mergeRiskValue(metadata *ToolMetadata, incoming string, incomingPresent bool, rank int, origin, reviewReason, path string) error {
if metadata == nil || !incomingPresent {
return nil
}
recordStringFieldCandidate(metadata, "risk", incoming, true, rank, origin, reviewReason)
return mergeRankedStringValue(
&metadata.Risk, &metadata.riskPresent, &metadata.riskRank, &metadata.riskOrigin,
incoming, true, rank, origin, path, "risk",
)
}
func mergeConfirmation(metadata *ToolMetadata, incoming string, rank int, origin, reviewReason, path string) error {
return mergeConfirmationValue(metadata, incoming, strings.TrimSpace(incoming) != "", rank, origin, reviewReason, path)
}
func mergeConfirmationValue(metadata *ToolMetadata, incoming string, incomingPresent bool, rank int, origin, reviewReason, path string) error {
if metadata == nil || !incomingPresent {
return nil
}
recordStringFieldCandidate(metadata, "confirmation", incoming, true, rank, origin, reviewReason)
return mergeRankedStringValue(
&metadata.Confirmation, &metadata.confirmationPresent, &metadata.confirmationRank, &metadata.confirmationOrigin,
incoming, true, rank, origin, path, "confirmation",
)
}
func scalarIncomingWon(previousValue string, previousPresent bool, previousRank int, previousOrigin, incoming string, incomingPresent bool, incomingRank int, incomingOrigin, finalOrigin string) bool {
if !incomingPresent {
return false
}
incoming = strings.TrimSpace(incoming)
if !previousPresent || incomingRank > previousRank {
return true
}
return incomingRank == previousRank && previousValue == incoming &&
strings.TrimSpace(finalOrigin) == strings.TrimSpace(incomingOrigin) &&
strings.TrimSpace(previousOrigin) != strings.TrimSpace(finalOrigin)
}
func selectionPrecedence(rank int) string {
switch rank {
case selectionRankContractFinal:
return selectionPrecedenceContractFinal
case selectionRankReviewedManual:
return selectionPrecedenceReviewedManual
case selectionRankReviewedExplicit:
return selectionPrecedenceReviewedExplicit
case selectionRankExplicit:
return selectionPrecedenceExplicit
case selectionRankImported:
return selectionPrecedenceImported
case selectionRankUnreviewedExplicit:
return selectionPrecedenceUnreviewedExplicit
case selectionRankSkill:
return selectionPrecedenceSkill
case selectionRankMCPFallback:
return selectionPrecedenceMCPFallback
default:
return selectionPrecedenceDefault
}
}
func recordFieldCandidate(metadata *ToolMetadata, field, value string, rank int, source, reviewReason string) {
recordStringFieldCandidate(metadata, field, value, strings.TrimSpace(value) != "", rank, source, reviewReason)
}
func recordStringFieldCandidate(metadata *ToolMetadata, field, value string, present bool, rank int, source, reviewReason string) {
if !present {
return
}
recordTypedFieldCandidateValue(metadata, field, strings.TrimSpace(value), true, rank, source, reviewReason)
}
func recordListFieldCandidate(metadata *ToolMetadata, field string, value []string, present bool, rank int, source, reviewReason string) {
if !listIsPresent(value, present) {
return
}
value = normalizeAuthoredStrings(value)
recordTypedFieldCandidate(metadata, field, cloneStringList(value), rank, source, reviewReason)
}
func recordProductListCandidate(metadata *ProductMetadata, field string, value []string, present bool, rank int, source string) {
if metadata == nil || !listIsPresent(value, present) {
return
}
value = normalizeAuthoredStrings(value)
if metadata.fieldCandidates == nil {
metadata.fieldCandidates = map[string][]FieldCandidateProvenance{}
}
candidate := FieldCandidateProvenance{
Value: cloneStringList(value),
Source: firstNonEmpty(source, "unknown"),
Precedence: selectionPrecedence(rank),
}
for _, existing := range metadata.fieldCandidates[field] {
if fieldCandidateEqual(existing, candidate) {
return
}
}
metadata.fieldCandidates[field] = append(metadata.fieldCandidates[field], candidate)
}
func recordProductStringCandidate(metadata *ProductMetadata, field, value string, present bool, rank int, source string) {
if metadata == nil || !present {
return
}
value = strings.TrimSpace(value)
if metadata.fieldCandidates == nil {
metadata.fieldCandidates = map[string][]FieldCandidateProvenance{}
}
candidate := FieldCandidateProvenance{
Value: value,
Source: firstNonEmpty(source, "unknown"),
Precedence: selectionPrecedence(rank),
}
for _, existing := range metadata.fieldCandidates[field] {
if fieldCandidateEqual(existing, candidate) {
return
}
}
metadata.fieldCandidates[field] = append(metadata.fieldCandidates[field], candidate)
}
func recordTypedFieldCandidate(metadata *ToolMetadata, field string, value any, rank int, source, reviewReason string) {
recordTypedFieldCandidateValue(metadata, field, value, value != nil, rank, source, reviewReason)
}
func recordTypedFieldCandidateValue(metadata *ToolMetadata, field string, value any, present bool, rank int, source, reviewReason string) {
if metadata == nil || !present {
return
}
if metadata.fieldCandidates == nil {
metadata.fieldCandidates = map[string][]FieldCandidateProvenance{}
}
candidate := FieldCandidateProvenance{
Value: cloneFieldValue(value),
Source: firstNonEmpty(source, "unknown"),
Precedence: selectionPrecedence(rank),
ReviewReason: strings.TrimSpace(reviewReason),
}
for index, existing := range metadata.fieldCandidates[field] {
if fieldValueEqual(existing.Value, candidate.Value) && existing.Source == candidate.Source && existing.Precedence == candidate.Precedence {
if existing.ReviewReason == "" && candidate.ReviewReason != "" {
metadata.fieldCandidates[field][index].ReviewReason = candidate.ReviewReason
}
return
}
}
metadata.fieldCandidates[field] = append(metadata.fieldCandidates[field], candidate)
}
func mergeFieldCandidateHistory(target *ToolMetadata, incoming ToolMetadata) {
if target == nil || len(incoming.fieldCandidates) == 0 {
return
}
if target.fieldCandidates == nil {
target.fieldCandidates = map[string][]FieldCandidateProvenance{}
}
for field, candidates := range incoming.fieldCandidates {
for _, candidate := range candidates {
exists := false
for _, current := range target.fieldCandidates[field] {
if fieldCandidateEqual(current, candidate) {
exists = true
break
}
}
if !exists {
target.fieldCandidates[field] = append(target.fieldCandidates[field], candidate)
}
}
}
}
// validateToolFieldCandidateConflicts checks every scalar and authored-list
// precedence layer, including non-winning layers. A higher-ranked candidate
// selects the final value, but it must not hide contradictory inputs at a
// lower rank.
func validateToolFieldCandidateConflicts(file File) error {
productIDs := make([]string, 0, len(file.Products))
for productID := range file.Products {
productIDs = append(productIDs, productID)
}
sort.Strings(productIDs)
for _, productID := range productIDs {
if err := validateFieldCandidateConflicts("product "+productID, file.Products[productID].fieldCandidates); err != nil {
return err
}
}
paths := make([]string, 0, len(file.Tools))
for path := range file.Tools {
paths = append(paths, path)
}
sort.Strings(paths)
for _, path := range paths {
if err := validateFieldCandidateConflicts(path, file.Tools[path].fieldCandidates); err != nil {
return err
}
}
return nil
}
func validateFieldCandidateConflicts(path string, history map[string][]FieldCandidateProvenance) error {
fields := make([]string, 0, len(history))
for field := range history {
fields = append(fields, field)
}
sort.Strings(fields)
for _, field := range fields {
candidates := append([]FieldCandidateProvenance(nil), history[field]...)
sort.Slice(candidates, func(i, j int) bool {
left, right := candidates[i], candidates[j]
leftRank, rightRank := precedenceRank(left.Precedence), precedenceRank(right.Precedence)
if leftRank != rightRank {
return leftRank > rightRank
}
if left.Source != right.Source {
return left.Source < right.Source
}
if !fieldValueEqual(left.Value, right.Value) {
return fieldValueKey(left.Value) < fieldValueKey(right.Value)
}
return left.Precedence < right.Precedence
})
for start := 0; start < len(candidates); {
rank := precedenceRank(candidates[start].Precedence)
end := start + 1
for end < len(candidates) && precedenceRank(candidates[end].Precedence) == rank {
end++
}
reference := candidates[start]
for _, candidate := range candidates[start+1 : end] {
if !fieldValueEqual(candidate.Value, reference.Value) {
return fmt.Errorf(
"agent metadata conflict for %s field %s at precedence %d: %s from %s conflicts with %s from %s",
path, field, rank,
fieldValueDisplay(reference.Value), firstNonEmpty(reference.Source, "<unknown>"),
fieldValueDisplay(candidate.Value), firstNonEmpty(candidate.Source, "<unknown>"),
)
}
}
start = end
}
}
return nil
}
func fieldWinnerReviewReason(metadata ToolMetadata, field, value, source string, rank int) string {
return fieldWinnerReviewReasonValue(metadata, field, strings.TrimSpace(value), source, rank)
}
func fieldWinnerReviewReasonValue(metadata ToolMetadata, field string, value any, source string, rank int) string {
precedence := selectionPrecedence(rank)
for _, candidate := range metadata.fieldCandidates[field] {
if fieldValueEqual(candidate.Value, value) && candidate.Source == firstNonEmpty(source, "unknown") && candidate.Precedence == precedence {
return candidate.ReviewReason
}
}
return ""
}
func syncToolFieldProvenance(metadata *ToolMetadata) {
if metadata == nil {
return
}
for _, field := range []string{"use_when", "avoid_when", "prerequisites", "tips", "workflow_refs", "examples"} {
coalesceSkillListCandidates(metadata.fieldCandidates, field)
}
provenance := map[string]FieldProvenance{}
addValue := func(field string, value any, present bool, source string, rank int) {
if !present {
return
}
source = firstNonEmpty(source, "unknown")
reviewReason := fieldWinnerReviewReasonValue(*metadata, field, value, source, rank)
recordTypedFieldCandidateValue(metadata, field, value, true, rank, source, reviewReason)
winner := FieldCandidateProvenance{
Value: cloneFieldValue(value),
Source: source,
Precedence: selectionPrecedence(rank),
ReviewReason: reviewReason,
}
candidates := make([]FieldCandidateProvenance, 0, len(metadata.fieldCandidates[field]))
for _, candidate := range metadata.fieldCandidates[field] {
candidate.Selected = fieldValueEqual(candidate.Value, winner.Value) && candidate.Source == winner.Source && candidate.Precedence == winner.Precedence
candidates = append(candidates, candidate)
}
sort.Slice(candidates, func(i, j int) bool {
if candidates[i].Selected != candidates[j].Selected {
return candidates[i].Selected
}
leftRank := precedenceRank(candidates[i].Precedence)
rightRank := precedenceRank(candidates[j].Precedence)
if leftRank != rightRank {
return leftRank > rightRank
}
if candidates[i].Source != candidates[j].Source {
return candidates[i].Source < candidates[j].Source
}
return fieldValueKey(candidates[i].Value) < fieldValueKey(candidates[j].Value)
})
provenance[field] = FieldProvenance{
Value: cloneFieldValue(winner.Value),
Source: source,
Precedence: selectionPrecedence(rank),
Resolution: "highest_precedence",
ReviewReason: reviewReason,
Candidates: candidates,
}
}
addString := func(field, value string, present bool, source string, rank int) {
addValue(field, strings.TrimSpace(value), present, source, rank)
}
addList := func(field string, value []string, present bool, source string, rank int) {
if !listIsPresent(value, present) {
return
}
value = normalizeAuthoredStrings(value)
rank = effectiveSelectionListRank(value, true, rank)
source = firstNonEmpty(source, "unknown")
reviewReason := fieldWinnerReviewReasonValue(*metadata, field, value, source, rank)
recordListFieldCandidate(metadata, field, value, true, rank, source, reviewReason)
winner := FieldCandidateProvenance{
Value: cloneStringList(value),
Source: source,
Precedence: selectionPrecedence(rank),
ReviewReason: reviewReason,
}
candidates := make([]FieldCandidateProvenance, 0, len(metadata.fieldCandidates[field]))
for _, candidate := range metadata.fieldCandidates[field] {
candidate.Selected = fieldValueEqual(candidate.Value, winner.Value) && candidate.Source == winner.Source && candidate.Precedence == winner.Precedence
candidates = append(candidates, candidate)
}
sort.Slice(candidates, func(i, j int) bool {
if candidates[i].Selected != candidates[j].Selected {
return candidates[i].Selected
}
leftRank := precedenceRank(candidates[i].Precedence)
rightRank := precedenceRank(candidates[j].Precedence)
if leftRank != rightRank {
return leftRank > rightRank
}
if candidates[i].Source != candidates[j].Source {
return candidates[i].Source < candidates[j].Source
}
return fieldValueKey(candidates[i].Value) < fieldValueKey(candidates[j].Value)
})
provenance[field] = FieldProvenance{
Value: winner.Value,
Source: source,
Precedence: selectionPrecedence(rank),
Resolution: "highest_precedence",
ReviewReason: reviewReason,
Candidates: candidates,
}
}
addString("effect", metadata.Effect, scalarIsPresent(metadata.Effect, metadata.effectPresent), firstNonEmpty(metadata.effectOrigin, metadata.EffectSource), metadata.effectRank)
addString("risk", metadata.Risk, scalarIsPresent(metadata.Risk, metadata.riskPresent), metadata.riskOrigin, metadata.riskRank)
addString("confirmation", metadata.Confirmation, scalarIsPresent(metadata.Confirmation, metadata.confirmationPresent), metadata.confirmationOrigin, metadata.confirmationRank)
addValue("interface_ref", interfaceRefCandidateValue(metadata.InterfaceRef), metadata.InterfaceRef != nil || metadata.interfaceRefPresent, metadata.interfaceRefOrigin, metadata.interfaceRefRank)
addString("interface_mode", metadata.InterfaceMode, scalarIsPresent(metadata.InterfaceMode, metadata.interfaceModePresent), metadata.interfaceModeOrigin, metadata.interfaceModeRank)
addString("availability", metadata.Availability, scalarIsPresent(metadata.Availability, metadata.availabilityPresent), metadata.availabilityOrigin, metadata.availabilityRank)
addString("interface_reason", metadata.InterfaceReason, scalarIsPresent(metadata.InterfaceReason, metadata.interfaceReasonPresent), metadata.interfaceReasonOrigin, metadata.interfaceReasonRank)
addString("agent_summary", metadata.AgentSummary, scalarIsPresent(metadata.AgentSummary, metadata.agentSummaryPresent), firstNonEmpty(metadata.agentSummaryOrigin, metadata.AgentSummarySource), metadata.agentSummaryRank)
addString("idempotency", metadata.Idempotency, scalarIsPresent(metadata.Idempotency, metadata.idempotencyPresent), metadata.idempotencyOrigin, metadata.idempotencyRank)
if metadata.Reviewed != nil {
addValue("reviewed", *metadata.Reviewed, true, metadata.reviewedOrigin, metadata.reviewedRank)
}
addList("use_when", metadata.UseWhen, metadata.useWhenPresent, metadata.useWhenOrigin, metadata.useWhenRank)
addList("avoid_when", metadata.AvoidWhen, metadata.avoidWhenPresent, metadata.avoidWhenOrigin, metadata.avoidWhenRank)
addList("prerequisites", metadata.Prerequisites, metadata.prerequisitesPresent, metadata.prerequisitesOrigin, metadata.prerequisitesRank)
addList("tips", metadata.Tips, metadata.tipsPresent, metadata.tipsOrigin, metadata.tipsRank)
addList("workflow_refs", metadata.WorkflowRefs, metadata.workflowRefsPresent, metadata.workflowRefsOrigin, metadata.workflowRefsRank)
addList("examples", metadata.Examples, metadata.examplesPresent, metadata.examplesOrigin, metadata.examplesRank)
if len(provenance) == 0 {
metadata.FieldProvenance = nil
return
}
metadata.FieldProvenance = provenance
}
func syncProductFieldProvenance(metadata *ProductMetadata) {
if metadata == nil {
return
}
for _, field := range []string{"use_when", "avoid_when"} {
coalesceSkillListCandidates(metadata.fieldCandidates, field)
}
provenance := map[string]FieldProvenance{}
if scalarIsPresent(metadata.AgentSummary, metadata.agentSummaryPresent) {
value := strings.TrimSpace(metadata.AgentSummary)
rank := metadata.agentSummaryRank
source := firstNonEmpty(metadata.agentSummaryOrigin, metadata.AgentSummarySource, "unknown")
recordProductStringCandidate(metadata, "agent_summary", value, true, rank, source)
winner := FieldCandidateProvenance{
Value: value,
Source: source,
Precedence: selectionPrecedence(rank),
}
candidates := make([]FieldCandidateProvenance, 0, len(metadata.fieldCandidates["agent_summary"]))
for _, candidate := range metadata.fieldCandidates["agent_summary"] {
candidate.Selected = fieldValueEqual(candidate.Value, winner.Value) && candidate.Source == winner.Source && candidate.Precedence == winner.Precedence
candidates = append(candidates, candidate)
}
sort.Slice(candidates, func(i, j int) bool {
if candidates[i].Selected != candidates[j].Selected {
return candidates[i].Selected
}
leftRank, rightRank := precedenceRank(candidates[i].Precedence), precedenceRank(candidates[j].Precedence)
if leftRank != rightRank {
return leftRank > rightRank
}
if candidates[i].Source != candidates[j].Source {
return candidates[i].Source < candidates[j].Source
}
return fieldValueKey(candidates[i].Value) < fieldValueKey(candidates[j].Value)
})
provenance["agent_summary"] = FieldProvenance{
Value: winner.Value,
Source: source,
Precedence: selectionPrecedence(rank),
Resolution: "highest_precedence",
Candidates: candidates,
}
}
for _, list := range []struct {
field string
value []string
present bool
source string
rank int
}{
{"use_when", metadata.UseWhen, metadata.useWhenPresent, metadata.useWhenOrigin, metadata.useWhenRank},
{"avoid_when", metadata.AvoidWhen, metadata.avoidWhenPresent, metadata.avoidWhenOrigin, metadata.avoidWhenRank},
} {
if !listIsPresent(list.value, list.present) {
continue
}
value := normalizeAuthoredStrings(list.value)
rank := effectiveSelectionListRank(value, true, list.rank)
source := firstNonEmpty(list.source, "unknown")
recordProductListCandidate(metadata, list.field, value, true, rank, source)
winner := FieldCandidateProvenance{
Value: cloneStringList(value),
Source: source,
Precedence: selectionPrecedence(rank),
}
candidates := make([]FieldCandidateProvenance, 0, len(metadata.fieldCandidates[list.field]))
for _, candidate := range metadata.fieldCandidates[list.field] {
candidate.Selected = fieldValueEqual(candidate.Value, winner.Value) && candidate.Source == winner.Source && candidate.Precedence == winner.Precedence
candidates = append(candidates, candidate)
}
sort.Slice(candidates, func(i, j int) bool {
if candidates[i].Selected != candidates[j].Selected {
return candidates[i].Selected
}
leftRank, rightRank := precedenceRank(candidates[i].Precedence), precedenceRank(candidates[j].Precedence)
if leftRank != rightRank {
return leftRank > rightRank
}
if candidates[i].Source != candidates[j].Source {
return candidates[i].Source < candidates[j].Source
}
return fieldValueKey(candidates[i].Value) < fieldValueKey(candidates[j].Value)
})
provenance[list.field] = FieldProvenance{
Value: winner.Value,
Source: source,
Precedence: selectionPrecedence(rank),
Resolution: "highest_precedence",
Candidates: candidates,
}
}
if len(provenance) == 0 {
metadata.FieldProvenance = nil
return
}
metadata.FieldProvenance = provenance
}
func precedenceRank(precedence string) int {
switch strings.TrimSpace(precedence) {
case selectionPrecedenceContractFinal:
return selectionRankContractFinal
case selectionPrecedenceReviewedManual:
return selectionRankReviewedManual
case selectionPrecedenceReviewedExplicit:
return selectionRankReviewedExplicit
case selectionPrecedenceExplicit:
return selectionRankExplicit
case selectionPrecedenceImported:
return selectionRankImported
case selectionPrecedenceUnreviewedExplicit:
return selectionRankUnreviewedExplicit
case selectionPrecedenceSkill:
return selectionRankSkill
case selectionPrecedenceMCPFallback:
return selectionRankMCPFallback
default:
return selectionRankDefault
}
}
func loadSources(opts Options) ([]sourceFile, error) {
paths := []string{
resolvePath(opts.Root, opts.SkillPath),
resolvePath(opts.Root, opts.IntentGuidePath),
}
productPaths := []string{}
productsRoot := resolvePath(opts.Root, opts.ProductsDir)
err := filepath.WalkDir(productsRoot, func(path string, entry fs.DirEntry, walkErr error) error {
if walkErr != nil {
return walkErr
}
if entry.IsDir() || !strings.EqualFold(filepath.Ext(entry.Name()), ".md") {
return nil
}
productPaths = append(productPaths, path)
return nil
})
if err != nil {
return nil, fmt.Errorf("walk product references: %w", err)
}
paths = append(paths, productPaths...)
if hintsDir := strings.TrimSpace(opts.HintsDir); hintsDir != "" {
return nil, fmt.Errorf("schema_hints/ is retired; clear HintsDir and declare ProductDecl/ContractFinal instead (got %q)", hintsDir)
}
if manualHints := strings.TrimSpace(opts.ManualHintsPath); manualHints != "" {
return nil, fmt.Errorf("manual hints are retired; clear ManualHintsPath and declare ProductDecl/ContractFinal instead (got %q)", manualHints)
}
if strings.TrimSpace(opts.InterfaceMetadataPath) != "" {
paths = append(paths, resolvePath(opts.Root, opts.InterfaceMetadataPath))
}
sort.Strings(paths)
files := make([]sourceFile, 0, len(paths))
seen := map[string]bool{}
for _, path := range paths {
path = filepath.Clean(path)
if path == "." || seen[path] {
continue
}
seen[path] = true
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("read %s: %w", path, err)
}
files = append(files, sourceFile{path: path, display: displayPath(opts.Root, path), data: data})
}
return files, nil
}
func sourceProductIDs(file sourceFile, productsRoot string, references []commandReference, surfaceProducts map[string]bool) []string {
relative, err := filepath.Rel(productsRoot, file.path)
if err == nil {
parts := strings.Split(filepath.ToSlash(relative), "/")
if len(parts) > 1 && strings.TrimSpace(parts[0]) != "" {
return []string{strings.TrimSpace(parts[0])}
}
}
base := strings.TrimSuffix(filepath.Base(file.path), filepath.Ext(file.path))
commandProducts := map[string]bool{}
for _, reference := range references {
if productID := firstCommandToken(normalizeCommandPath(reference.text)); productID != "" {
commandProducts[productID] = true
}
}
if commandProducts[base] {
return []string{base}
}
if len(surfaceProducts) > 0 {
matches := []string{}
for productID := range surfaceProducts {
if base == productID || strings.HasPrefix(base, productID+"-") {
matches = append(matches, productID)
}
}
if len(matches) > 0 {
sort.Slice(matches, func(i, j int) bool {
return len(matches[i]) > len(matches[j])
})
return matches[:1]
}
}
if len(commandProducts) > 0 {
return sortedBoolKeys(commandProducts)
}
if base == "" {
return nil
}
return []string{base}
}
func collectCommandReferences(body string) []commandReference {
lines := strings.Split(body, "\n")
references := []commandReference{}
inFence := false
shellFence := false
commentIntent := ""
for index := 0; index < len(lines); index++ {
line := strings.TrimSpace(lines[index])
if strings.HasPrefix(line, "```") {
if inFence {
inFence = false
shellFence = false
} else {
inFence = true
shellFence = isShellFence(strings.TrimSpace(strings.TrimPrefix(line, "```")))
}
commentIntent = ""
continue
}
if shellFence {
switch {
case line == "":
commentIntent = ""
case strings.HasPrefix(line, "#"):
commentIntent = shellCommentIntent(line)
continue
}
}
if !strings.HasPrefix(line, "dws ") {
continue
}
startLine := index + 1
parts := []string{}
for {
part := strings.TrimSpace(lines[index])
continued := strings.HasSuffix(part, "\\")
if continued {
part = strings.TrimSpace(strings.TrimSuffix(part, "\\"))
}
if part != "" {
parts = append(parts, part)
}
if !continued || index+1 >= len(lines) {
break
}
index++
}
command := strings.TrimSpace(strings.Join(parts, " "))
if command != "" {
references = append(references, commandReference{
text: command,
line: startLine,
commentIntent: commentIntent,
})
}
}
return references
}
func sortedBoolKeys(values map[string]bool) []string {
keys := make([]string, 0, len(values))
for key, included := range values {
if included && strings.TrimSpace(key) != "" {
keys = append(keys, strings.TrimSpace(key))
}
}
sort.Strings(keys)
return keys
}
func (tracker sourceTracker) add(toolPath, source string, line int) {
toolPath = normalizeCommandPath(toolPath)
if len(strings.Fields(toolPath)) < 2 {
return
}
if tracker[toolPath] == nil {
tracker[toolPath] = map[string]sourceLocation{}
}
location := sourceLocation{source: strings.TrimSpace(source), line: line}
key := location.source + "\x00" + fmt.Sprintf("%09d", location.line)
tracker[toolPath][key] = location
}
func (tracker sourceTracker) locations(toolPath string) []sourceLocation {
byKey := tracker[toolPath]
locations := make([]sourceLocation, 0, len(byKey))
for _, location := range byKey {
locations = append(locations, location)
}
sort.Slice(locations, func(i, j int) bool {
if locations[i].source != locations[j].source {
return locations[i].source < locations[j].source
}
return locations[i].line < locations[j].line
})
return locations
}
func candidateToolPaths(skillPath string, toolPaths map[string]string, limit int) []string {
if limit <= 0 {
return nil
}
canonical := map[string]bool{}
for _, path := range toolPaths {
if path = strings.TrimSpace(path); path != "" {
canonical[path] = true
}
}
type scoredPath struct {
path string
score int
}
scored := []scoredPath{}
for path := range canonical {
score := commandPathSimilarity(skillPath, path)
if score > 0 {
scored = append(scored, scoredPath{path: path, score: score})
}
}
sort.Slice(scored, func(i, j int) bool {
if scored[i].score != scored[j].score {
return scored[i].score > scored[j].score
}
return scored[i].path < scored[j].path
})
if len(scored) > limit {
scored = scored[:limit]
}
out := make([]string, 0, len(scored))
for _, item := range scored {
out = append(out, item.path)
}
return out
}
func commandPathSimilarity(left, right string) int {
leftParts := strings.Fields(left)
rightParts := strings.Fields(right)
if len(leftParts) == 0 || len(rightParts) == 0 {
return 0
}
score := 0
if leftParts[0] == rightParts[0] {
score += 6
}
for leftIndex, rightIndex := len(leftParts)-1, len(rightParts)-1; leftIndex >= 0 && rightIndex >= 0; leftIndex, rightIndex = leftIndex-1, rightIndex-1 {
if leftParts[leftIndex] != rightParts[rightIndex] {
break
}
score += 5
}
rightTokens := map[string]bool{}
for _, token := range rightParts {
rightTokens[token] = true
}
for _, token := range leftParts {
if rightTokens[token] {
score++
}
}
if score < 5 {
return 0
}
return score
}
func resolvePath(root, path string) string {
if filepath.IsAbs(path) {
return filepath.Clean(path)
}
return filepath.Clean(filepath.Join(root, path))
}
func displayPath(root, path string) string {
rel, err := filepath.Rel(filepath.Clean(root), filepath.Clean(path))
if err != nil || strings.HasPrefix(rel, "..") {
return filepath.ToSlash(filepath.Clean(path))
}
return filepath.ToSlash(rel)
}
func hashSources(files []sourceFile) string {
h := sha256.New()
for _, file := range files {
_, _ = h.Write([]byte(file.display))
_, _ = h.Write([]byte{0})
_, _ = h.Write(file.data)
_, _ = h.Write([]byte{0})
}
return "sha256:" + hex.EncodeToString(h.Sum(nil))
}
func parseProductRouting(out *File, body, source string) {
section := markdownSection(body, "## 意图判断决策树")
for _, line := range strings.Split(section, "\n") {
match := quotedIntentRE.FindStringSubmatch(line)
target := routeCodeTarget(line)
if len(match) < 2 || target == "" {
continue
}
productID := firstCommandToken(target)
if productID == "" {
continue
}
addProductUse(out, productID, cleanIntent(match[1]), source)
}
}
func parseIntentGuide(out *File, body, source string, origins sourceTracker) {
section, startLine := markdownSectionAt(body, "## 易混淆场景快速对照表")
for index, line := range strings.Split(section, "\n") {
columns := markdownTableColumns(line)
if len(columns) < 5 || columns[0] == "用户说..." || strings.Trim(columns[0], "- ") == "" {
continue
}
scenario := cleanIntent(columns[0])
if intent := cleanIntent(columns[1]); intent != "" && intent != scenario {
scenario += ";" + intent
}
for _, target := range codeSpans(columns[2]) {
addTargetUse(out, target, scenario, source)
origins.add(normalizeCommandPath(target), source, startLine+index)
}
for _, target := range codeSpans(columns[3]) {
addTargetAvoid(out, target, scenario, source)
origins.add(normalizeCommandPath(target), source, startLine+index)
}
}
}
func parseToolIntents(out *File, productIDs, known []string, body, source string, origins sourceTracker) {
for _, heading := range []string{"## 意图判断", "## 使用场景"} {
section, startLine := markdownSectionAt(body, heading)
if section == "" {
continue
}
currentIntent := ""
scanner := bufio.NewScanner(strings.NewReader(section))
lineIndex := 0
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
lineNumber := startLine + lineIndex
lineIndex++
if match := quotedIntentRE.FindStringSubmatch(line); len(match) > 1 {
currentIntent = cleanIntent(match[1])
if strings.Contains(line, "→") || strings.Contains(line, "->") {
if target := routeCodeTarget(line); target != "" {
if path := resolveToolPath(productIDs, target, known); path != "" {
addToolUse(out, path, currentIntent, source)
origins.add(path, source, lineNumber)
}
}
currentIntent = ""
}
continue
}
if currentIntent == "" || (!strings.Contains(line, "→") && !strings.Contains(line, "->")) {
continue
}
target := routeCodeTarget(line)
if target == "" {
continue
}
action := strings.TrimSpace(strings.TrimLeft(strings.Split(strings.Split(line, "→")[0], "->")[0], "-* "))
intent := currentIntent
if action != "" {
intent += ";" + action
}
if path := resolveToolPath(productIDs, target, known); path != "" {
addToolUse(out, path, intent, source)
origins.add(path, source, lineNumber)
}
}
}
}
func parseExamples(out *File, known []string, references []commandReference, source string, maxExamples int, origins sourceTracker) error {
if len(known) == 0 {
return nil
}
for _, reference := range references {
line := reference.text
if strings.Contains(line, "[flags]") || len(line) > 320 {
continue
}
path := longestKnownPrefix(commandTokens(line), known)
if path == "" {
continue
}
metadata := out.Tools[path]
if reference.commentIntent != "" {
_ = appendToolListValue(&metadata, "use_when", &metadata.UseWhen, &metadata.useWhenPresent, &metadata.useWhenRank, &metadata.useWhenOrigin, reference.commentIntent, selectionRankSkill, source, path)
metadata.SourceRefs = append(metadata.SourceRefs, source)
}
if len(metadata.Examples) < maxExamples {
_ = appendToolListValue(&metadata, "examples", &metadata.Examples, &metadata.examplesPresent, &metadata.examplesRank, &metadata.examplesOrigin, line, selectionRankSkill, source, path)
metadata.SourceRefs = append(metadata.SourceRefs, source)
}
ensureEffect(&metadata, path)
if err := applyExplicitCommentSafety(&metadata, reference.commentIntent, source, path); err != nil {
return err
}
out.Tools[path] = metadata
origins.add(path, source, reference.line)
}
return nil
}
func isShellFence(language string) bool {
switch strings.ToLower(strings.TrimSpace(language)) {
case "", "bash", "console", "sh", "shell", "zsh":
return true
default:
return false
}
}
func shellCommentIntent(line string) string {
intent := cleanIntent(strings.TrimSpace(strings.TrimPrefix(strings.TrimSpace(line), "#")))
intent = strings.TrimSpace(stepCommentRE.ReplaceAllString(intent, ""))
if intent == "" || strings.HasPrefix(intent, "!") || strings.HasPrefix(intent, "→") || len(intent) > 200 {
return ""
}
return intent
}
func applyExplicitCommentSafety(metadata *ToolMetadata, intent, source, path string) error {
if metadata == nil || metadata.Effect == "" || metadata.Effect == "read" {
return nil
}
explicitRisk := false
for _, marker := range []string{"不可逆", "不可恢复", "不能撤销", "二次确认", "立即失效", "需确认", "需要确认", "高风险", "高影响"} {
if strings.Contains(intent, marker) {
explicitRisk = true
break
}
}
if !explicitRisk {
return nil
}
const reason = "Skill command comment explicitly marks the operation as risky"
if err := mergeEffect(metadata, dangerEffect(intent), "skill-comment", selectionRankSkill, source, reason, path); err != nil {
return err
}
if err := mergeRisk(metadata, "high", selectionRankSkill, source, reason, path); err != nil {
return err
}
return mergeConfirmation(metadata, "user_required", selectionRankSkill, source, reason, path)
}
func parseDangerRules(out *File, body, source string, stats *Stats, origins sourceTracker) error {
section, startLine := markdownSectionAt(body, "## 危险操作确认")
for index, line := range strings.Split(section, "\n") {
columns := markdownTableColumns(line)
if len(columns) < 3 || columns[0] == "产品" || strings.Trim(columns[0], "- ") == "" {
continue
}
products := codeSpans(columns[0])
commands := codeSpans(columns[1])
if len(products) == 0 || len(commands) == 0 {
continue
}
productID := firstCommandToken(products[0])
for _, command := range commands {
path := normalizeToolPath(productID, command)
if path == "" {
continue
}
metadata := out.Tools[path]
const reason = "Skill danger table explicitly reviews this operation"
if err := mergeEffect(&metadata, dangerEffect(columns[2]), "skill-explicit", selectionRankSkill, source, reason, path); err != nil {
return err
}
if err := mergeRisk(&metadata, "high", selectionRankSkill, source, reason, path); err != nil {
return err
}
if err := mergeConfirmation(&metadata, "user_required", selectionRankSkill, source, reason, path); err != nil {
return err
}
metadata.SourceRefs = append(metadata.SourceRefs, source)
out.Tools[path] = metadata
origins.add(path, source, startLine+index)
stats.RiskRules++
}
}
return nil
}
func dangerEffect(description string) string {
for _, token := range []string{"删除", "撤回", "拒绝", "移除", "替换", "不可逆", "清空"} {
if strings.Contains(description, token) {
return "destructive"
}
}
return "write"
}
func collectCommandPaths(productIDs []string, references []commandReference) []string {
allowedProducts := map[string]bool{}
for _, productID := range productIDs {
if productID = strings.TrimSpace(productID); productID != "" {
allowedProducts[productID] = true
}
}
paths := map[string]bool{}
for _, reference := range references {
path := normalizeCommandPath(reference.text)
if allowedProducts[firstCommandToken(path)] {
paths[path] = true
}
}
out := make([]string, 0, len(paths))
for path := range paths {
out = append(out, path)
}
sort.Slice(out, func(i, j int) bool {
leftParts := len(strings.Fields(out[i]))
rightParts := len(strings.Fields(out[j]))
if leftParts != rightParts {
return leftParts > rightParts
}
return out[i] < out[j]
})
return out
}
func routeCodeTarget(line string) string {
arrow := strings.Index(line, "→")
arrowWidth := len("→")
if asciiArrow := strings.Index(line, "->"); arrow < 0 || (asciiArrow >= 0 && asciiArrow < arrow) {
arrow = asciiArrow
arrowWidth = len("->")
}
if arrow < 0 {
return ""
}
spans := codeSpans(line[arrow+arrowWidth:])
if len(spans) == 0 {
return ""
}
return spans[0]
}
func resolveToolPath(productIDs []string, raw string, known []string) string {
candidate := normalizeCommandPath(raw)
if candidate == "" {
return ""
}
for _, path := range known {
if candidate == path {
return path
}
}
productSet := map[string]bool{}
for _, productID := range productIDs {
productID = strings.TrimSpace(productID)
if productID == "" {
continue
}
productSet[productID] = true
prefixed := strings.TrimSpace(productID + " " + candidate)
for _, path := range known {
if prefixed == path {
return path
}
}
}
if productSet[firstCommandToken(candidate)] {
return candidate
}
matches := []string{}
for _, path := range known {
if strings.HasSuffix(path, " "+candidate) {
matches = append(matches, path)
}
}
if len(matches) == 1 {
return matches[0]
}
if len(productIDs) == 1 {
return strings.TrimSpace(productIDs[0] + " " + candidate)
}
return ""
}
func normalizeToolPath(productID, raw string) string {
raw = strings.TrimSpace(raw)
raw = strings.TrimPrefix(raw, "dws ")
path := normalizeCommandPath(raw)
if path == "" {
return ""
}
if strings.HasPrefix(path, productID+" ") || path == productID {
return path
}
return strings.TrimSpace(productID + " " + path)
}
func normalizeCommandPath(raw string) string {
tokens := commandTokens(raw)
if len(tokens) > 0 && tokens[0] == "dws" {
tokens = tokens[1:]
}
return strings.Join(tokens, " ")
}
func commandTokens(raw string) []string {
fields := strings.Fields(strings.TrimSpace(raw))
out := make([]string, 0, len(fields))
for _, field := range fields {
field = strings.Trim(field, "`(),;:")
if field == "" || strings.HasPrefix(field, "#") || strings.HasPrefix(field, "--") || strings.HasPrefix(field, "<") || strings.HasPrefix(field, "[") || strings.HasPrefix(field, "{") || strings.HasPrefix(field, "\"") || strings.HasPrefix(field, "'") || strings.Contains(field, "|") || strings.Contains(field, "=") {
break
}
out = append(out, field)
}
return out
}
func longestKnownPrefix(tokens []string, known []string) string {
if len(tokens) > 0 && tokens[0] == "dws" {
tokens = tokens[1:]
}
joined := strings.Join(tokens, " ")
for _, path := range known {
if joined == path || strings.HasPrefix(joined, path+" ") {
return path
}
}
return ""
}
func ensureEffect(metadata *ToolMetadata, path string) {
if metadata == nil || scalarIsPresent(metadata.Effect, metadata.effectPresent) {
return
}
if effect := classifyEffectPath(path); effect != "" {
_ = mergeEffect(metadata, effect, "command-verb", selectionRankDefault, "command-verb", "", path)
}
}
func classifyEffectPath(path string) string {
parts := strings.Fields(strings.ToLower(strings.TrimSpace(path)))
for _, part := range parts[1:] {
if effect := classifyEffectVerb(part); effect != "" {
return effect
}
}
return ""
}
func classifyEffectVerb(verb string) string {
verb = strings.ToLower(strings.TrimSpace(verb))
read := map[string]bool{
"list": true, "get": true, "search": true, "read": true, "query": true,
"detail": true, "status": true, "download": true, "export": true,
"info": true, "summary": true, "check": true, "inspect": true,
"diagnose": true, "types": true, "records": true, "tasks": true,
"find": true, "result": true, "resolve": true, "suggest": true,
"fields": true, "stats": true, "rules": true, "keywords": true,
"transcription": true, "todos": true, "audio": true, "mine": true,
"person": true, "enterprise": true, "behavior": true, "bots": true,
"invite-url": true, "conversation-info": true, "read-status": true,
"upload-info": true, "search-options": true, "history-list": true,
"share-url": true, "rag-pretest": true, "widgets-example": true,
"config-example": true, "legacy-search-open-platform": true,
}
write := map[string]bool{
"create": true, "update": true, "delete": true, "send": true, "submit": true,
"approve": true, "reject": true, "revoke": true, "add": true, "remove": true,
"insert": true, "upload": true, "move": true, "rename": true, "reply": true,
"recall": true, "publish": true, "enable": true, "disable": true, "save": true,
"replace": true, "respond": true, "redirect-task": true, "oa-comments": true,
"oa-cc-noticer": true, "config": true, "connect": true, "reset": true,
"start": true, "stop": true, "subscribe": true, "unsubscribe": true,
"browser-policy": true, "chmod": true, "copy": true, "sort": true,
"forward": true, "fill": true, "upsert": true, "transfer": true,
"resume": true, "pause": true, "reorder": true, "mute": true,
"mkdir": true, "duplicate": true, "complete": true, "commit": true,
"cancel": true, "arrange": true, "append": true, "done": true,
"import": true, "new": true, "lock": true, "dismiss": true,
"quit": true, "clear": true, "csv-put": true,
}
if read[verb] || hasAnyPrefix(verb, "list-", "get-", "query-", "search-", "read-", "download-", "export-", "inspect-", "check-") || hasAnySuffix(verb, "-list", "-get", "-query", "-search", "-read", "-download", "-export") {
return "read"
}
if write[verb] || hasAnyPrefix(verb,
"create-", "update-", "delete-", "send-", "add-", "remove-",
"set-", "unset-", "move-", "copy-", "insert-", "upload-",
"replace-", "reset-", "enable-", "disable-", "start-", "stop-",
"subscribe-", "unsubscribe-", "recall-", "reply-", "forward-",
"clear-", "merge-", "unmerge-", "write-", "append-", "commit-",
"complete-", "cancel-", "transfer-", "batch-", "role-create",
"role-update", "role-delete") || hasAnySuffix(verb,
"-create", "-update", "-delete", "-send", "-add", "-remove",
"-set", "-move", "-copy", "-insert", "-upload", "-replace",
"-enable", "-disable", "-forward", "-clear", "-write", "-put",
"-mute") || hasHyphenToken(verb, "mute") {
return "write"
}
return ""
}
func hasHyphenToken(value string, tokens ...string) bool {
parts := strings.Split(value, "-")
for _, part := range parts {
for _, token := range tokens {
if part == token {
return true
}
}
}
return false
}
func hasAnyPrefix(value string, prefixes ...string) bool {
for _, prefix := range prefixes {
if strings.HasPrefix(value, prefix) {
return true
}
}
return false
}
func hasAnySuffix(value string, suffixes ...string) bool {
for _, suffix := range suffixes {
if strings.HasSuffix(value, suffix) {
return true
}
}
return false
}
func applyDefaultSafety(metadata *ToolMetadata) {
if metadata == nil || strings.TrimSpace(metadata.Effect) == "" {
return
}
if !scalarIsPresent(metadata.Risk, metadata.riskPresent) {
switch metadata.Effect {
case "read":
metadata.Risk = "low"
case "destructive":
metadata.Risk = "high"
default:
metadata.Risk = "medium"
}
metadata.riskRank = selectionRankDefault
metadata.riskOrigin = "effect-default"
metadata.riskPresent = true
recordFieldCandidate(metadata, "risk", metadata.Risk, metadata.riskRank, metadata.riskOrigin, "")
}
if !scalarIsPresent(metadata.Confirmation, metadata.confirmationPresent) {
if metadata.Risk == "high" {
metadata.Confirmation = "user_required"
} else {
metadata.Confirmation = "not_required"
}
metadata.confirmationRank = selectionRankDefault
metadata.confirmationOrigin = "risk-default"
metadata.confirmationPresent = true
recordFieldCandidate(metadata, "confirmation", metadata.Confirmation, metadata.confirmationRank, metadata.confirmationOrigin, "")
}
if !scalarIsPresent(metadata.Idempotency, metadata.idempotencyPresent) {
if metadata.Effect == "read" {
metadata.Idempotency = "idempotent"
} else {
metadata.Idempotency = "unknown"
}
metadata.idempotencyRank = selectionRankDefault
metadata.idempotencyOrigin = "effect-default"
metadata.idempotencyPresent = true
recordFieldCandidate(metadata, "idempotency", metadata.Idempotency, metadata.idempotencyRank, metadata.idempotencyOrigin, "")
}
}
func appendRankedStringListValue(target *[]string, targetPresent *bool, targetRank *int, targetOrigin *string, value string, rank int, source, path, field string) error {
value = strings.TrimSpace(value)
if value == "" {
return nil
}
current := normalizeAuthoredStrings(*target)
if listIsPresent(*target, *targetPresent) && *targetRank == rank &&
(strings.TrimSpace(*targetOrigin) == strings.TrimSpace(source) || rank == selectionRankSkill) {
*target = normalizeAuthoredStrings(append(current, value))
*targetPresent = true
if rank == selectionRankSkill {
// Parsed Skill rows are fragments of one logical authored array, not
// independent whole-field candidates. Aggregate them before the
// precedence resolver; same-rank conflict remains strict for every
// complete candidate (hints and reconciled ToolMetadata).
*targetOrigin = combinedSkillSource(*targetOrigin, source)
}
return nil
}
return mergeRankedStringList(target, targetPresent, targetRank, targetOrigin, []string{value}, true, rank, source, path, field)
}
func appendToolListValue(metadata *ToolMetadata, field string, target *[]string, targetPresent *bool, targetRank *int, targetOrigin *string, value string, rank int, source, path string) error {
if metadata == nil {
return nil
}
if err := appendRankedStringListValue(target, targetPresent, targetRank, targetOrigin, value, rank, source, path, field); err != nil {
upsertToolListCandidate(metadata, field, []string{value}, rank, source)
return err
}
candidate := []string{value}
candidateSource := source
if *targetRank == rank && (strings.TrimSpace(*targetOrigin) == strings.TrimSpace(source) || rank == selectionRankSkill) {
candidate = *target
candidateSource = *targetOrigin
}
upsertToolListCandidate(metadata, field, candidate, rank, candidateSource)
return nil
}
func appendProductListValue(metadata *ProductMetadata, field string, target *[]string, targetPresent *bool, targetRank *int, targetOrigin *string, value string, rank int, source, path string) error {
if metadata == nil {
return nil
}
if err := appendRankedStringListValue(target, targetPresent, targetRank, targetOrigin, value, rank, source, path, field); err != nil {
upsertProductListCandidate(metadata, field, []string{value}, rank, source)
return err
}
candidate := []string{value}
candidateSource := source
if *targetRank == rank && (strings.TrimSpace(*targetOrigin) == strings.TrimSpace(source) || rank == selectionRankSkill) {
candidate = *target
candidateSource = *targetOrigin
}
upsertProductListCandidate(metadata, field, candidate, rank, candidateSource)
return nil
}
func upsertToolListCandidate(metadata *ToolMetadata, field string, values []string, rank int, source string) {
if metadata == nil {
return
}
if metadata.fieldCandidates == nil {
metadata.fieldCandidates = map[string][]FieldCandidateProvenance{}
}
metadata.fieldCandidates[field] = upsertListCandidate(metadata.fieldCandidates[field], values, rank, source)
}
func upsertProductListCandidate(metadata *ProductMetadata, field string, values []string, rank int, source string) {
if metadata == nil {
return
}
if metadata.fieldCandidates == nil {
metadata.fieldCandidates = map[string][]FieldCandidateProvenance{}
}
metadata.fieldCandidates[field] = upsertListCandidate(metadata.fieldCandidates[field], values, rank, source)
}
func upsertListCandidate(candidates []FieldCandidateProvenance, values []string, rank int, source string) []FieldCandidateProvenance {
values = normalizeAuthoredStrings(values)
if len(values) == 0 {
return candidates
}
source = firstNonEmpty(source, "unknown")
precedence := selectionPrecedence(rank)
candidate := FieldCandidateProvenance{Value: append([]string(nil), values...), Source: source, Precedence: precedence}
if rank == selectionRankSkill {
filtered := candidates[:0]
for _, existing := range candidates {
if existing.Precedence != precedence {
filtered = append(filtered, existing)
}
}
return append(filtered, candidate)
}
for index := range candidates {
if candidates[index].Source == source && candidates[index].Precedence == precedence {
candidates[index] = candidate
return candidates
}
}
return append(candidates, candidate)
}
func combinedSkillSource(existing, incoming string) string {
parts := make([]string, 0, 2)
for _, source := range []string{existing, incoming} {
for _, item := range strings.Split(source, " + ") {
if item = strings.TrimSpace(item); item != "" {
parts = append(parts, item)
}
}
}
return strings.Join(normalizedStrings(parts), " + ")
}
func coalesceSkillListCandidates(history map[string][]FieldCandidateProvenance, field string) {
if len(history) == 0 {
return
}
candidates := history[field]
indices := make([]int, 0, len(candidates))
for index, candidate := range candidates {
if candidate.Precedence == selectionPrecedenceSkill {
indices = append(indices, index)
}
}
if len(indices) <= 1 {
return
}
sort.Slice(indices, func(i, j int) bool {
return candidates[indices[i]].Source < candidates[indices[j]].Source
})
values := make([]string, 0)
source := ""
for _, index := range indices {
if list, ok := candidates[index].Value.([]string); ok {
values = append(values, list...)
}
source = combinedSkillSource(source, candidates[index].Source)
}
aggregated := FieldCandidateProvenance{
Value: normalizeAuthoredStrings(values),
Source: source,
Precedence: selectionPrecedenceSkill,
}
filtered := candidates[:0]
for _, candidate := range candidates {
if candidate.Precedence != selectionPrecedenceSkill {
filtered = append(filtered, candidate)
}
}
history[field] = append(filtered, aggregated)
}
func addTargetUse(out *File, target, intent, source string) {
target = normalizeCommandPath(target)
if target == "" || target == "先追问" {
return
}
if len(strings.Fields(target)) == 1 {
addProductUse(out, target, intent, source)
return
}
addToolUse(out, target, intent, source)
}
func addTargetAvoid(out *File, target, intent, source string) {
target = normalizeCommandPath(target)
if target == "" {
return
}
if len(strings.Fields(target)) == 1 {
metadata := out.Products[target]
_ = appendProductListValue(&metadata, "avoid_when", &metadata.AvoidWhen, &metadata.avoidWhenPresent, &metadata.avoidWhenRank, &metadata.avoidWhenOrigin, intent, selectionRankSkill, source, target)
metadata.SourceRefs = append(metadata.SourceRefs, source)
out.Products[target] = metadata
return
}
metadata := out.Tools[target]
_ = appendToolListValue(&metadata, "avoid_when", &metadata.AvoidWhen, &metadata.avoidWhenPresent, &metadata.avoidWhenRank, &metadata.avoidWhenOrigin, intent, selectionRankSkill, source, target)
metadata.SourceRefs = append(metadata.SourceRefs, source)
ensureEffect(&metadata, target)
out.Tools[target] = metadata
}
func addProductUse(out *File, productID, intent, source string) {
productID = strings.TrimSpace(productID)
intent = cleanIntent(intent)
if productID == "" || intent == "" {
return
}
metadata := out.Products[productID]
_ = appendProductListValue(&metadata, "use_when", &metadata.UseWhen, &metadata.useWhenPresent, &metadata.useWhenRank, &metadata.useWhenOrigin, intent, selectionRankSkill, source, productID)
metadata.SourceRefs = append(metadata.SourceRefs, source)
out.Products[productID] = metadata
}
func addToolUse(out *File, path, intent, source string) {
path = normalizeCommandPath(path)
intent = cleanIntent(intent)
if path == "" || intent == "" {
return
}
metadata := out.Tools[path]
_ = appendToolListValue(&metadata, "use_when", &metadata.UseWhen, &metadata.useWhenPresent, &metadata.useWhenRank, &metadata.useWhenOrigin, intent, selectionRankSkill, source, path)
metadata.SourceRefs = append(metadata.SourceRefs, source)
ensureEffect(&metadata, path)
out.Tools[path] = metadata
}
func normalizeFile(file *File, maxExamples int) {
for key, metadata := range file.Products {
metadata.AgentSummary = strings.TrimSpace(metadata.AgentSummary)
metadata.AgentSummarySource = strings.TrimSpace(metadata.AgentSummarySource)
metadata.UseWhen = normalizeAuthoredStrings(metadata.UseWhen)
metadata.AvoidWhen = normalizeAuthoredStrings(metadata.AvoidWhen)
preserveExplicitEmptyProductLists(&metadata)
metadata.SourceRefs = normalizedStrings(metadata.SourceRefs)
syncProductFieldProvenance(&metadata)
file.Products[key] = metadata
}
for key, metadata := range file.Tools {
ensureEffect(&metadata, key)
applyDefaultSafety(&metadata)
metadata.AgentSummary = strings.TrimSpace(metadata.AgentSummary)
metadata.AgentSummarySource = strings.TrimSpace(metadata.AgentSummarySource)
metadata.UseWhen = normalizeAuthoredStrings(metadata.UseWhen)
metadata.AvoidWhen = normalizeAuthoredStrings(metadata.AvoidWhen)
metadata.Prerequisites = normalizeAuthoredStrings(metadata.Prerequisites)
metadata.Tips = normalizeAuthoredStrings(metadata.Tips)
metadata.WorkflowRefs = normalizeAuthoredStrings(metadata.WorkflowRefs)
metadata.Examples = normalizeAuthoredStrings(metadata.Examples)
if maxExamples > 0 && len(metadata.Examples) > maxExamples {
metadata.Examples = metadata.Examples[:maxExamples]
}
preserveExplicitEmptyToolLists(&metadata)
normalizeListFieldCandidates(&metadata, maxExamples)
metadata.SourceRefs = normalizedStrings(metadata.SourceRefs)
if metadata.InterfaceRef != nil {
metadata.InterfaceRef.ProductID = strings.TrimSpace(metadata.InterfaceRef.ProductID)
metadata.InterfaceRef.RPCName = strings.TrimSpace(metadata.InterfaceRef.RPCName)
}
syncToolFieldProvenance(&metadata)
file.Tools[key] = metadata
}
}
// finalizeInterfaceDispositions applies the cross-field interface matrix only
// after every source and alias has been reconciled. Keeping it out of
// normalizeFile makes resolution associative: an early local candidate cannot
// erase a lower-ranked MCP ref before a later higher-ranked mode is merged.
func finalizeInterfaceDispositions(file *File) {
if file == nil {
return
}
for key, metadata := range file.Tools {
mode := strings.TrimSpace(metadata.InterfaceMode)
availability := strings.TrimSpace(metadata.Availability)
if mode != "local" && mode != "composite" && availability != "unavailable" {
continue
}
current := metadata.FieldProvenance["interface_ref"]
allCandidates := append([]FieldCandidateProvenance(nil), current.Candidates...)
allCandidates = append(allCandidates, current.OverriddenCandidates...)
source := firstNonEmpty(metadata.interfaceModeOrigin, "interface_mode")
rank := effectiveSelectionRank(metadata.InterfaceMode, metadata.interfaceModeRank)
reason := "final interface mode " + mode + " forbids a direct MCP interface_ref"
if availability == "unavailable" {
source = firstNonEmpty(metadata.availabilityOrigin, "availability")
rank = effectiveSelectionRank(metadata.Availability, metadata.availabilityRank)
reason = "final availability unavailable forbids Agent invocation and a direct MCP interface_ref"
}
winner := FieldCandidateProvenance{
Value: nil,
Source: source,
Precedence: selectionPrecedence(rank),
Selected: true,
ReviewReason: reason,
}
candidates := []FieldCandidateProvenance{winner}
overridden := make([]FieldCandidateProvenance, 0, len(allCandidates))
for _, candidate := range allCandidates {
candidate.Selected = false
if candidate.Value == nil || fieldStringValue(candidate.Value) == "" || fieldStringValue(candidate.Value) == "<none>" {
candidate.Value = nil
// The matrix winner already represents an authored nil from the
// same source/rank. Keep one selected candidate, but retain a nil
// authored at another source/rank as an auditable candidate.
if candidate.Source != winner.Source || candidate.Precedence != winner.Precedence {
candidates = append(candidates, candidate)
}
continue
}
overridden = append(overridden, candidate)
}
metadata.InterfaceRef = nil
metadata.interfaceRefPresent = true
if metadata.FieldProvenance == nil {
metadata.FieldProvenance = map[string]FieldProvenance{}
}
metadata.FieldProvenance["interface_ref"] = FieldProvenance{
Value: winner.Value,
Source: winner.Source,
Precedence: winner.Precedence,
Resolution: "interface_disposition_matrix",
ReviewReason: reason,
Candidates: candidates,
OverriddenCandidates: overridden,
}
file.Tools[key] = metadata
}
}
// validateInterfaceDispositions keeps implementation mechanism and execution
// availability orthogonal. Only mcp/local/composite are modes; unavailable is
// an Agent execution gate and therefore always needs a reviewed explanation.
func validateInterfaceDispositions(file File) error {
var problems []string
for key, metadata := range file.Tools {
mode := strings.TrimSpace(metadata.InterfaceMode)
availability := strings.TrimSpace(metadata.Availability)
reason := strings.TrimSpace(metadata.InterfaceReason)
// The generator can be used for partial metadata audits which have not
// selected an interface disposition yet. Once any interface field is
// declared, however, it must satisfy the complete final matrix. The
// release Catalog gate separately requires every effective command to
// carry such a disposition.
if mode == "" && availability == "" && reason == "" && metadata.InterfaceRef == nil {
continue
}
if mode == "unavailable" {
problems = append(problems, fmt.Sprintf("Agent metadata tool %s uses legacy interface_mode=unavailable; migrate to interface_mode=mcp, local, or composite with availability=unavailable", key))
continue
}
if mode != "mcp" && mode != "local" && mode != "composite" {
problems = append(problems, fmt.Sprintf("Agent metadata tool %s has unsupported interface_mode %q", key, mode))
continue
}
if availability != "available" && availability != "unavailable" {
problems = append(problems, fmt.Sprintf("Agent metadata tool %s has unsupported availability %q", key, availability))
continue
}
if availability == "unavailable" {
if metadata.InterfaceRef != nil {
problems = append(problems, fmt.Sprintf("Agent metadata tool %s is unavailable but declares interface_ref", key))
}
if reason == "" {
problems = append(problems, fmt.Sprintf("Agent metadata tool %s is unavailable without interface_reason", key))
}
continue
}
switch mode {
case "mcp":
if metadata.InterfaceRef == nil {
problems = append(problems, fmt.Sprintf("Agent metadata tool %s is available mcp without interface_ref", key))
}
case "local":
if metadata.InterfaceRef != nil {
problems = append(problems, fmt.Sprintf("Agent metadata tool %s is available local but declares interface_ref", key))
}
case "composite":
if metadata.InterfaceRef != nil {
problems = append(problems, fmt.Sprintf("Agent metadata tool %s is available composite but declares a single interface_ref", key))
}
if reason == "" {
problems = append(problems, fmt.Sprintf("Agent metadata tool %s is available composite without interface_reason", key))
}
}
}
if len(problems) == 0 {
return nil
}
sort.Strings(problems)
return fmt.Errorf("invalid final Agent interface disposition: %s", strings.Join(problems, "; "))
}
func uniqueStringsInOrder(values []string) []string {
seen := map[string]bool{}
out := make([]string, 0, len(values))
for _, value := range values {
value = strings.TrimSpace(value)
if value == "" || seen[value] {
continue
}
seen[value] = true
out = append(out, value)
}
if len(out) == 0 {
return nil
}
return out
}
func metadataProductID(path string) string {
first := firstCommandToken(path)
if index := strings.Index(first, "."); index > 0 {
return first[:index]
}
return first
}
func normalizedStrings(values []string) []string {
seen := map[string]bool{}
out := make([]string, 0, len(values))
for _, value := range values {
value = strings.TrimSpace(value)
if value == "" || seen[value] {
continue
}
seen[value] = true
out = append(out, value)
}
sort.Strings(out)
if len(out) == 0 {
return nil
}
return out
}
func normalizeAuthoredStrings(values []string) []string {
if values == nil {
return nil
}
values = uniqueStringsInOrder(values)
if values == nil {
return []string{}
}
return values
}
func markdownSection(body, heading string) string {
section, _ := markdownSectionAt(body, heading)
return section
}
func markdownSectionAt(body, heading string) (string, int) {
lines := strings.Split(body, "\n")
start := -1
for index, line := range lines {
if strings.TrimSpace(line) == heading {
start = index + 1
break
}
}
if start < 0 {
return "", 0
}
end := len(lines)
for index := start; index < len(lines); index++ {
if strings.HasPrefix(strings.TrimSpace(lines[index]), "## ") {
end = index
break
}
}
for start < end && strings.TrimSpace(lines[start]) == "" {
start++
}
for end > start && strings.TrimSpace(lines[end-1]) == "" {
end--
}
return strings.Join(lines[start:end], "\n"), start + 1
}
func markdownTableColumns(line string) []string {
line = strings.TrimSpace(line)
if !strings.HasPrefix(line, "|") || !strings.HasSuffix(line, "|") {
return nil
}
raw := strings.Split(strings.Trim(line, "|"), "|")
out := make([]string, 0, len(raw))
for _, value := range raw {
out = append(out, strings.TrimSpace(value))
}
return out
}
func codeSpans(value string) []string {
matches := codeSpanRE.FindAllStringSubmatch(value, -1)
out := make([]string, 0, len(matches))
for _, match := range matches {
if len(match) > 1 && strings.TrimSpace(match[1]) != "" {
out = append(out, strings.TrimSpace(match[1]))
}
}
return out
}
func firstCommandToken(value string) string {
tokens := commandTokens(value)
if len(tokens) > 0 && tokens[0] == "dws" {
tokens = tokens[1:]
}
if len(tokens) == 0 {
return ""
}
return tokens[0]
}
func cleanIntent(value string) string {
value = strings.TrimSpace(value)
value = strings.Trim(value, "\"“”' ")
value = strings.ReplaceAll(value, "**", "")
value = strings.ReplaceAll(value, "`", "")
return strings.TrimSpace(value)
}