bf9395e022
CI / license-header (push) Has been skipped
CI / e2e-dry-run (push) Has been skipped
CI / fast-gate (push) Failing after 0s
Test PR Label Logic / test-pr-labels (push) Failing after 1s
Skill Format Check / check-format (push) Failing after 2s
CI / security (push) Failing after 5s
CI / unit-test (push) Has been skipped
CI / lint (push) Has been skipped
CI / script-test (push) Has been skipped
CI / deterministic-gate (push) Has been skipped
CI / coverage (push) Has been skipped
CI / results (push) Has been cancelled
CI / deadcode (push) Has been cancelled
CI / e2e-live (push) Has been cancelled
72 lines
2.2 KiB
Go
72 lines
2.2 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package platform
|
|
|
|
import "fmt"
|
|
|
|
// Risk is the three-tier risk taxonomy declared on every command.
|
|
//
|
|
// A defined type (not an alias of string) so plugin authors get
|
|
// compile-time + IDE candidate help when passing the constants below.
|
|
// Crossing the string boundary (yaml, cobra annotation) goes through
|
|
// ParseRisk so typos surface as `risk_invalid` rather than silently
|
|
// flowing through.
|
|
type Risk string
|
|
|
|
const (
|
|
RiskRead Risk = "read"
|
|
RiskWrite Risk = "write"
|
|
RiskHighRiskWrite Risk = "high-risk-write"
|
|
)
|
|
|
|
// riskOrder maps the Risk taxonomy to a comparable rank. The pruning
|
|
// engine compares ranks for the MaxRisk axis.
|
|
var riskOrder = map[Risk]int{
|
|
RiskRead: 0,
|
|
RiskWrite: 1,
|
|
RiskHighRiskWrite: 2,
|
|
}
|
|
|
|
// ParseRisk converts a raw string (yaml, cobra annotation) into a Risk.
|
|
//
|
|
// - s == "" → ("", nil) "not specified"
|
|
// - s 在闭合枚举 → (Risk(s), nil) OK
|
|
// - s 不在枚举内 → ("", error) invalid
|
|
//
|
|
// The (absent vs invalid) split mirrors the cmdpolicy engine's
|
|
// risk_not_annotated vs risk_invalid reason codes — callers can treat
|
|
// the "" + nil case as "not specified" without losing the distinction
|
|
// from a typo.
|
|
//
|
|
// Matching is strict: "Read" / "READ" / " read " are all rejected.
|
|
// annotation is developer code, not user input — strict matching is
|
|
// the typo-catch mechanism, not a normalisation opportunity.
|
|
func ParseRisk(s string) (Risk, error) {
|
|
if s == "" {
|
|
return "", nil
|
|
}
|
|
r := Risk(s)
|
|
if _, ok := riskOrder[r]; !ok {
|
|
return "", fmt.Errorf("invalid risk %q: must be read|write|high-risk-write", s)
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// IsValid reports whether r is one of the three recognised values.
|
|
func (r Risk) IsValid() bool {
|
|
_, ok := riskOrder[r]
|
|
return ok
|
|
}
|
|
|
|
// Rank returns the comparable rank of r. ok=false when r is not in the
|
|
// closed taxonomy.
|
|
func (r Risk) Rank() (rank int, ok bool) {
|
|
rank, ok = riskOrder[r]
|
|
return rank, ok
|
|
}
|
|
|
|
// String returns the underlying string. Useful for yaml/json output
|
|
// and cobra annotation injection.
|
|
func (r Risk) String() string { return string(r) }
|