chore: import upstream snapshot with attribution
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

This commit is contained in:
wehub-resource-sync
2026-07-13 12:22:54 +08:00
commit bf9395e022
2349 changed files with 588574 additions and 0 deletions
@@ -0,0 +1,92 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package main
import (
"encoding/json"
"flag"
"fmt"
"os"
"github.com/larksuite/cli/errs"
"github.com/larksuite/cli/internal/qualitygate/publiccontent"
"github.com/larksuite/cli/internal/qualitygate/report"
"github.com/larksuite/cli/internal/validate"
"github.com/larksuite/cli/internal/vfs"
)
type eventPayload struct {
Comment *struct {
Body string `json:"body"`
} `json:"comment"`
Review *struct {
Body string `json:"body"`
} `json:"review"`
}
func main() {
eventPath := flag.String("event", os.Getenv("GITHUB_EVENT_PATH"), "GitHub event payload path")
kind := flag.String("kind", os.Getenv("GITHUB_EVENT_NAME"), "GitHub event kind")
flag.Parse()
if *eventPath == "" {
fmt.Fprintln(os.Stderr, "comment-audit: --event or GITHUB_EVENT_PATH is required")
os.Exit(2)
}
body, err := commentBody(*eventPath)
if err != nil {
fmt.Fprintf(os.Stderr, "comment-audit: %v\n", err)
os.Exit(2)
}
diags := diagnostics(publiccontent.ScanComment(*kind, body))
if len(diags) > 0 {
fmt.Fprintln(os.Stderr, auditFailureSummary(len(diags)))
}
report.Print(os.Stderr, diags)
os.Exit(report.ExitCode(diags))
}
func auditFailureSummary(count int) string {
return fmt.Sprintf("post-publication audit found public content findings: %d", count)
}
func commentBody(path string) (string, error) {
safePath, err := validate.SafeInputPath(path)
if err != nil {
return "", errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --event: %v", err).
WithParam("--event").
WithCause(err)
}
data, err := vfs.ReadFile(safePath)
if err != nil {
return "", err
}
var payload eventPayload
if err := json.Unmarshal(data, &payload); err != nil {
return "", err
}
switch {
case payload.Comment != nil:
return payload.Comment.Body, nil
case payload.Review != nil:
return payload.Review.Body, nil
default:
return "", nil
}
}
func diagnostics(items []publiccontent.Finding) []report.Diagnostic {
out := make([]report.Diagnostic, 0, len(items))
for _, item := range items {
out = append(out, report.Diagnostic{
Rule: item.Rule,
Action: item.Action,
File: item.File,
Line: item.Line,
Message: item.Message,
Suggestion: item.Suggestion,
})
}
return out
}
@@ -0,0 +1,70 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package main
import (
"errors"
"os"
"path/filepath"
"testing"
"github.com/larksuite/cli/errs"
)
func TestCommentBodyReadsSafeRelativeEventPath(t *testing.T) {
dir := t.TempDir()
if err := writeTestFile(filepath.Join(dir, "event.json"), `{"comment":{"body":"clean comment"}}`); err != nil {
t.Fatal(err)
}
origDir, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
if err := os.Chdir(dir); err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
_ = os.Chdir(origDir)
})
got, err := commentBody("event.json")
if err != nil {
t.Fatalf("commentBody() error = %v", err)
}
if got != "clean comment" {
t.Fatalf("comment body = %q", got)
}
}
func TestCommentBodyRejectsUnsafeEventPath(t *testing.T) {
path := filepath.Join(t.TempDir(), "event.json")
if err := writeTestFile(path, `{"comment":{"body":"clean"}}`); err != nil {
t.Fatal(err)
}
_, err := commentBody(path)
problem, ok := errs.ProblemOf(err)
if err == nil || !ok {
t.Fatalf("commentBody(%q) error = %v, want unsafe path validation error", path, err)
}
if problem.Category != errs.CategoryValidation || problem.Subtype != errs.SubtypeInvalidArgument {
t.Fatalf("commentBody(%q) problem = %#v, want invalid argument validation", path, problem)
}
var validationErr *errs.ValidationError
if !errors.As(err, &validationErr) || validationErr.Param != "--event" {
t.Fatalf("commentBody(%q) error = %v, want --event validation param", path, err)
}
}
func TestAuditFailureSummaryStatesPostPublicationAudit(t *testing.T) {
got := auditFailureSummary(2)
want := "post-publication audit found public content findings: 2"
if got != want {
t.Fatalf("auditFailureSummary() = %q, want %q", got, want)
}
}
func writeTestFile(path, data string) error {
return os.WriteFile(path, []byte(data), 0o644)
}
@@ -0,0 +1,174 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package main
import (
"context"
"io"
"sort"
"strings"
rootcmd "github.com/larksuite/cli/cmd"
"github.com/larksuite/cli/internal/cmdmeta"
"github.com/larksuite/cli/internal/cmdutil"
"github.com/larksuite/cli/internal/qualitygate/manifest"
"github.com/larksuite/cli/internal/registry"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
func collectHandAuthored(ctx context.Context) (manifest.Manifest, error) {
root := rootcmd.Build(ctx, cmdutil.InvocationContext{},
rootcmd.WithIO(strings.NewReader(""), io.Discard, io.Discard),
rootcmd.WithoutPlugins(),
rootcmd.WithoutStrictMode(),
rootcmd.WithoutServiceCommands(),
)
return collectFromRoot(root), nil
}
func collectCommandIndex(ctx context.Context) (manifest.Manifest, error) {
root := rootcmd.Build(ctx, cmdutil.InvocationContext{},
rootcmd.WithIO(strings.NewReader(""), io.Discard, io.Discard),
rootcmd.WithoutPlugins(),
rootcmd.WithoutStrictMode(),
rootcmd.WithServiceCatalog(registry.EmbeddedCatalog()),
)
idx := collectFromRoot(root)
handAuthored, err := collectHandAuthored(ctx)
if err != nil {
return manifest.Manifest{}, err
}
return overlayHandAuthoredCommands(idx, handAuthored), nil
}
func collectFromRoot(root *cobra.Command) manifest.Manifest {
var commands []manifest.Command
walkCommands(root, func(c *cobra.Command) {
if c == root {
return
}
commands = append(commands, commandFromCobra(c, nil))
})
sort.Slice(commands, func(i, j int) bool {
return commands[i].Path < commands[j].Path
})
return manifest.Manifest{SchemaVersion: 1, Commands: commands}
}
func overlayHandAuthoredCommands(idx, handAuthored manifest.Manifest) manifest.Manifest {
byPath := make(map[string]manifest.Command, len(handAuthored.Commands))
for _, cmd := range handAuthored.Commands {
byPath[cmd.Path] = cmd
}
for i, cmd := range idx.Commands {
if handCmd, ok := byPath[cmd.Path]; ok {
idx.Commands[i] = handCmd
}
}
return idx
}
func walkCommands(root *cobra.Command, visit func(*cobra.Command)) {
visit(root)
for _, child := range root.Commands() {
walkCommands(child, visit)
}
}
func commandFromCobra(c *cobra.Command, defaultFields map[string][]string) manifest.Command {
path := strings.TrimPrefix(c.CommandPath(), "lark-cli ")
source := manifest.SourceBuiltin
if s, ok := cmdmeta.SourceOf(c); ok {
source = manifest.Source(s)
}
entry := manifest.Command{
Path: path,
CanonicalPath: manifest.CanonicalCommandPath(path),
Domain: commandDomain(c, path, source),
Use: c.Use,
Short: c.Short,
Example: c.Example,
Hidden: c.Hidden,
Runnable: c.Runnable(),
Source: source,
Generated: cmdmeta.Generated(c),
Identities: cmdmeta.Identities(c),
DefaultFields: defaultFields[path],
}
if risk, ok := cmdmeta.Risk(c); ok {
entry.Risk = risk
}
c.Flags().VisitAll(func(f *pflag.Flag) {
entry.Flags = append(entry.Flags, flagFromPFlag(f))
})
c.InheritedFlags().VisitAll(func(f *pflag.Flag) {
if findFlag(entry.Flags, f.Name) == nil {
entry.Flags = append(entry.Flags, flagFromPFlag(f))
}
})
sort.Slice(entry.Flags, func(i, j int) bool {
return entry.Flags[i].Name < entry.Flags[j].Name
})
return entry
}
func commandDomain(c *cobra.Command, path string, source manifest.Source) string {
if domain := cmdmeta.Domain(c); domain != "" {
return domain
}
if source == manifest.SourceService {
if first, _, ok := strings.Cut(path, " "); ok {
return first
}
return path
}
return ""
}
func flagFromPFlag(f *pflag.Flag) manifest.Flag {
return manifest.Flag{
Name: f.Name,
Shorthand: f.Shorthand,
Usage: f.Usage,
Hidden: f.Hidden,
Required: hasAnnotation(f, cobra.BashCompOneRequiredFlag),
TakesValue: f.NoOptDefVal == "",
DefValue: f.DefValue,
NoOptValue: f.NoOptDefVal,
Annotations: cloneAnnotations(f.Annotations),
}
}
func findFlag(flags []manifest.Flag, name string) *manifest.Flag {
for i := range flags {
if flags[i].Name == name {
return &flags[i]
}
}
return nil
}
func hasAnnotation(f *pflag.Flag, key string) bool {
if f.Annotations == nil {
return false
}
values, ok := f.Annotations[key]
return ok && len(values) > 0
}
func cloneAnnotations(in map[string][]string) map[string][]string {
if len(in) == 0 {
return nil
}
out := make(map[string][]string, len(in))
for key, values := range in {
out[key] = append([]string(nil), values...)
}
return out
}
@@ -0,0 +1,83 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package main
import (
"context"
"flag"
"fmt"
"io"
"os"
"path/filepath"
"github.com/larksuite/cli/internal/qualitygate/manifest"
"github.com/larksuite/cli/internal/vfs"
)
func main() {
os.Exit(runManifestExport(os.Args[1:], os.Stderr))
}
func runManifestExport(args []string, stderr io.Writer) int {
configureManifestExportEnvironment()
fs := flag.NewFlagSet("manifest-export", flag.ContinueOnError)
fs.SetOutput(stderr)
var manifestOut string
var commandIndexOut string
fs.StringVar(&manifestOut, "manifest-out", "", "write hand-authored command manifest JSON to this path")
fs.StringVar(&commandIndexOut, "command-index-out", "", "write full command index JSON to this path")
if err := fs.Parse(args); err != nil {
fmt.Fprintf(stderr, "manifest-export: %v\n", err)
return 2
}
if manifestOut == "" || commandIndexOut == "" {
fmt.Fprintln(stderr, "manifest-export: --manifest-out and --command-index-out are required")
return 2
}
ctx := context.Background()
m, err := collectHandAuthored(ctx)
if err != nil {
fmt.Fprintf(stderr, "manifest-export: collect command manifest: %v\n", err)
return 2
}
idx, err := collectCommandIndex(ctx)
if err != nil {
fmt.Fprintf(stderr, "manifest-export: collect command index: %v\n", err)
return 2
}
if err := ensureParentDir(manifestOut); err != nil {
fmt.Fprintf(stderr, "manifest-export: create manifest output directory: %v\n", err)
return 2
}
if err := ensureParentDir(commandIndexOut); err != nil {
fmt.Fprintf(stderr, "manifest-export: create command index output directory: %v\n", err)
return 2
}
if err := manifest.WriteFile(manifestOut, manifest.KindCommandManifest, m); err != nil {
fmt.Fprintf(stderr, "manifest-export: write command manifest: %v\n", err)
return 2
}
if err := manifest.WriteFile(commandIndexOut, manifest.KindCommandIndex, idx); err != nil {
fmt.Fprintf(stderr, "manifest-export: write command index: %v\n", err)
return 2
}
return 0
}
func ensureParentDir(path string) error {
dir := filepath.Dir(path)
if dir == "." || dir == "" {
return nil
}
return vfs.MkdirAll(dir, 0o755)
}
func configureManifestExportEnvironment() {
_ = os.Setenv("LARKSUITE_CLI_REMOTE_META", "off")
if os.Getenv("LARKSUITE_CLI_CONFIG_DIR") == "" {
_ = os.Setenv("LARKSUITE_CLI_CONFIG_DIR", filepath.Join(os.TempDir(), "quality-gate-cli-config"))
}
}
@@ -0,0 +1,224 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package main
import (
"bytes"
"context"
"os"
"path/filepath"
"testing"
"github.com/larksuite/cli/internal/qualitygate/manifest"
)
func TestManifestExportWritesManifestAndCommandIndex(t *testing.T) {
dir := t.TempDir()
manifestPath := filepath.Join(dir, "command-manifest.json")
indexPath := filepath.Join(dir, "command-index.json")
code := runManifestExport([]string{
"--manifest-out", manifestPath,
"--command-index-out", indexPath,
}, &bytes.Buffer{})
if code != 0 {
t.Fatalf("exit code = %d", code)
}
m, err := manifest.ReadFile(manifestPath, manifest.KindCommandManifest)
if err != nil {
t.Fatal(err)
}
idx, err := manifest.ReadFile(indexPath, manifest.KindCommandIndex)
if err != nil {
t.Fatal(err)
}
if len(m.Commands) == 0 || len(idx.Commands) == 0 {
t.Fatalf("empty export: manifest=%d index=%d", len(m.Commands), len(idx.Commands))
}
if hasServiceCommand(m) {
t.Fatal("command-manifest should not include service commands")
}
if !hasServiceCommand(idx) {
t.Fatal("command-index should include service commands")
}
}
func TestManifestExportRequiresOutputPaths(t *testing.T) {
var stderr bytes.Buffer
code := runManifestExport(nil, &stderr)
if code != 2 {
t.Fatalf("exit code = %d", code)
}
if got := stderr.String(); !bytes.Contains([]byte(got), []byte("--manifest-out and --command-index-out are required")) {
t.Fatalf("stderr = %s", got)
}
}
func TestConfigureManifestExportEnvironmentForcesDeterministicRegistry(t *testing.T) {
t.Setenv("LARKSUITE_CLI_REMOTE_META", "on")
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", "")
configureManifestExportEnvironment()
if got := os.Getenv("LARKSUITE_CLI_REMOTE_META"); got != "off" {
t.Fatalf("LARKSUITE_CLI_REMOTE_META = %q, want off", got)
}
if got := os.Getenv("LARKSUITE_CLI_CONFIG_DIR"); got == "" {
t.Fatal("LARKSUITE_CLI_CONFIG_DIR was not set")
}
}
func TestCollectContainsDocsFetchAndDryRunFlag(t *testing.T) {
got, err := collectHandAuthored(context.Background())
if err != nil {
t.Fatalf("collectHandAuthored() error = %v", err)
}
cmd := findManifestCommand(&got, "docs +fetch")
if cmd == nil {
t.Fatalf("docs +fetch not found")
}
if !cmd.Runnable {
t.Fatalf("docs +fetch should be runnable")
}
if findManifestFlag(cmd, "dry-run") == nil {
t.Fatalf("docs +fetch should expose --dry-run")
}
if cmd.Source != manifest.SourceShortcut {
t.Fatalf("docs +fetch source = %q, want shortcut", cmd.Source)
}
}
func TestCollectExcludesGeneratedServiceCommands(t *testing.T) {
got, err := collectHandAuthored(context.Background())
if err != nil {
t.Fatalf("collectHandAuthored() error = %v", err)
}
for _, cmd := range got.Commands {
if cmd.Source == manifest.SourceService || cmd.Generated {
t.Fatalf("quality-gate manifest should not include generated service command: %#v", cmd)
}
}
}
func TestCollectCommandIndexIncludesEmbeddedServiceCommand(t *testing.T) {
got, err := collectCommandIndex(context.Background())
if err != nil {
t.Fatalf("collectCommandIndex() error = %v", err)
}
cmd := findManifestCommand(&got, "drive file.comments create_v2")
if cmd == nil {
t.Fatalf("drive file.comments create_v2 not found")
}
if cmd.Source != manifest.SourceService {
t.Fatalf("source = %q, want service", cmd.Source)
}
if !cmd.Generated {
t.Fatalf("service command should be marked generated")
}
if !cmd.Runnable {
t.Fatalf("service method command should be runnable")
}
for _, name := range []string{"file-token", "params", "data", "dry-run"} {
if findManifestFlag(cmd, name) == nil {
t.Fatalf("drive file.comments create_v2 should expose --%s", name)
}
}
}
func TestCollectCommandIndexDoesNotInheritGeneratedFromServiceParentForShortcut(t *testing.T) {
got, err := collectCommandIndex(context.Background())
if err != nil {
t.Fatalf("collectCommandIndex() error = %v", err)
}
cmd := findManifestCommand(&got, "docs +fetch")
if cmd == nil {
t.Fatalf("docs +fetch not found")
}
if cmd.Source != manifest.SourceShortcut {
t.Fatalf("docs +fetch source = %q, want shortcut", cmd.Source)
}
if cmd.Generated {
t.Fatalf("shortcut under service parent must not inherit generated=true")
}
}
func TestCollectCommandIndexPreservesHandAuthoredMetadataForOverlappingCommands(t *testing.T) {
handAuthored, err := collectHandAuthored(context.Background())
if err != nil {
t.Fatalf("collectHandAuthored() error = %v", err)
}
idx, err := collectCommandIndex(context.Background())
if err != nil {
t.Fatalf("collectCommandIndex() error = %v", err)
}
for _, handCmd := range handAuthored.Commands {
indexCmd := findManifestCommand(&idx, handCmd.Path)
if indexCmd == nil {
t.Fatalf("command-index missing hand-authored command %q", handCmd.Path)
}
if indexCmd.Source != handCmd.Source || indexCmd.Generated != handCmd.Generated {
t.Fatalf("command-index metadata for %q = source:%s generated:%v, want source:%s generated:%v", handCmd.Path, indexCmd.Source, indexCmd.Generated, handCmd.Source, handCmd.Generated)
}
}
}
func TestCollectDoesNotInheritGeneratedFromServiceParentForShortcut(t *testing.T) {
got, err := collectHandAuthored(context.Background())
if err != nil {
t.Fatalf("collectHandAuthored() error = %v", err)
}
cmd := findManifestCommand(&got, "docs +fetch")
if cmd == nil {
t.Fatalf("docs +fetch not found")
}
if cmd.Source != manifest.SourceShortcut {
t.Fatalf("docs +fetch source = %q, want shortcut", cmd.Source)
}
if cmd.Generated {
t.Fatalf("shortcut under service parent must not inherit generated=true")
}
}
func TestCollectIgnoresRuntimeStrictMode(t *testing.T) {
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())
t.Setenv("LARKSUITE_CLI_APP_ID", "dry-run")
t.Setenv("LARKSUITE_CLI_APP_SECRET", "dry-run")
t.Setenv("LARKSUITE_CLI_BRAND", "feishu")
got, err := collectHandAuthored(context.Background())
if err != nil {
t.Fatalf("collectHandAuthored() error = %v", err)
}
if cmd := findManifestCommand(&got, "contact +search-user"); cmd == nil {
t.Fatal("user-only shortcut missing; manifest collection should not apply runtime strict mode")
}
}
func hasServiceCommand(m manifest.Manifest) bool {
for _, cmd := range m.Commands {
if cmd.Source == manifest.SourceService {
return true
}
}
return false
}
func findManifestCommand(m *manifest.Manifest, path string) *manifest.Command {
for i := range m.Commands {
if m.Commands[i].Path == path {
return &m.Commands[i]
}
}
return nil
}
func findManifestFlag(cmd *manifest.Command, name string) *manifest.Flag {
for i := range cmd.Flags {
if cmd.Flags[i].Name == name {
return &cmd.Flags[i]
}
}
return nil
}
@@ -0,0 +1,111 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package main
import (
"context"
"flag"
"fmt"
"os"
"path/filepath"
"github.com/larksuite/cli/internal/qualitygate/manifest"
"github.com/larksuite/cli/internal/qualitygate/report"
"github.com/larksuite/cli/internal/qualitygate/rules"
"github.com/larksuite/cli/internal/validate"
)
func main() {
if len(os.Args) < 2 {
usageAndExit(2)
}
switch os.Args[1] {
case "check":
os.Exit(runCheck(os.Args[2:]))
default:
usageAndExit(2)
}
}
func runCheck(args []string) int {
configureQualityGateEnvironment()
fs := flag.NewFlagSet("check", flag.ContinueOnError)
opts := rules.Options{}
var printLegacyCommandCandidates bool
var printLegacyFlagCandidates bool
fs.StringVar(&opts.Repo, "repo", ".", "repository root")
fs.StringVar(&opts.CLIBin, "cli-bin", "./lark-cli", "lark-cli binary used for dry-run validation")
fs.StringVar(&opts.ChangedFrom, "changed-from", "", "base revision for incremental checks")
fs.StringVar(&opts.FactsOut, "facts-out", "", "write facts JSON to this path")
fs.StringVar(&opts.ManifestPath, "manifest", "", "hand-authored command manifest JSON")
fs.StringVar(&opts.CommandIndexPath, "command-index", "", "full command index JSON")
fs.StringVar(&opts.PublicContentMetadataPath, "public-content-metadata", "", "PR title/body metadata JSON for public content checks")
fs.BoolVar(&printLegacyCommandCandidates, "print-legacy-command-candidates", false, "print current non-kebab-case hand-authored command candidates")
fs.BoolVar(&printLegacyFlagCandidates, "print-legacy-flag-candidates", false, "print current non-kebab-case flag candidates")
if err := fs.Parse(args); err != nil {
fmt.Fprintf(os.Stderr, "quality-gate check: %v\n", err)
return 2
}
if opts.PublicContentMetadataPath != "" {
safePath, err := validate.SafeInputPath(opts.PublicContentMetadataPath)
if err != nil {
fmt.Fprintf(os.Stderr, "quality-gate check: --public-content-metadata: %v\n", err)
return 2
}
opts.PublicContentMetadataPath = safePath
}
if opts.ManifestPath == "" || opts.CommandIndexPath == "" {
fmt.Fprintln(os.Stderr, "quality-gate check: --manifest and --command-index are required")
return 2
}
if printLegacyCommandCandidates || printLegacyFlagCandidates {
m, err := manifest.ReadFile(opts.ManifestPath, manifest.KindCommandManifest)
if err != nil {
fmt.Fprintf(os.Stderr, "quality-gate check: --manifest: %v\n", err)
return 2
}
if printLegacyCommandCandidates {
for _, line := range rules.LegacyCommandCandidates(m) {
fmt.Fprintln(os.Stdout, line)
}
}
if printLegacyFlagCandidates {
for _, line := range rules.LegacyFlagCandidates(m) {
fmt.Fprintln(os.Stdout, line)
}
}
return 0
}
diags, facts, err := rules.Run(context.Background(), opts)
if err != nil {
fmt.Fprintf(os.Stderr, "quality-gate check: %v\n", err)
return 2
}
report.Print(os.Stderr, diags)
if opts.FactsOut != "" {
if err := facts.WriteFile(opts.FactsOut); err != nil {
fmt.Fprintf(os.Stderr, "quality-gate check: write facts: %v\n", err)
return 2
}
}
return report.ExitCode(diags)
}
func configureQualityGateEnvironment() {
_ = os.Setenv("LARKSUITE_CLI_REMOTE_META", "off")
if os.Getenv("LARKSUITE_CLI_CONFIG_DIR") == "" {
_ = os.Setenv("LARKSUITE_CLI_CONFIG_DIR", filepath.Join(os.TempDir(), "quality-gate-cli-config"))
}
}
func usageAndExit(code int) {
fmt.Fprintln(os.Stderr, "usage: quality-gate check")
os.Exit(code)
}
@@ -0,0 +1,122 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package main
import (
"io"
"os"
"path/filepath"
"strings"
"testing"
"github.com/larksuite/cli/internal/qualitygate/manifest"
)
func TestConfigureQualityGateEnvironmentForcesDeterministicRegistry(t *testing.T) {
t.Setenv("LARKSUITE_CLI_REMOTE_META", "on")
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", "")
configureQualityGateEnvironment()
if got := os.Getenv("LARKSUITE_CLI_REMOTE_META"); got != "off" {
t.Fatalf("LARKSUITE_CLI_REMOTE_META = %q, want off", got)
}
if got := os.Getenv("LARKSUITE_CLI_CONFIG_DIR"); got == "" {
t.Fatal("LARKSUITE_CLI_CONFIG_DIR was not set")
}
}
func TestCheckRequiresManifestInputs(t *testing.T) {
code, stderr := runCheckCaptureStderr(t, []string{"--repo", t.TempDir(), "--cli-bin", "./lark-cli"})
if code != 2 {
t.Fatalf("exit code = %d, stderr=%s", code, stderr)
}
if !strings.Contains(stderr, "--manifest and --command-index are required") {
t.Fatalf("stderr = %s", stderr)
}
}
func TestCheckAcceptsPublicContentMetadataFlag(t *testing.T) {
code, stderr := runCheckCaptureStderr(t, []string{
"--repo", t.TempDir(),
"--cli-bin", "./lark-cli",
"--public-content-metadata", ".tmp/quality-gate/pr.json",
})
if code != 2 {
t.Fatalf("exit code = %d, stderr=%s", code, stderr)
}
if strings.Contains(stderr, "flag provided but not defined") {
t.Fatalf("public content metadata flag was not registered: %s", stderr)
}
if !strings.Contains(stderr, "--manifest and --command-index are required") {
t.Fatalf("stderr = %s", stderr)
}
}
func TestCheckRejectsUnsafePublicContentMetadataPath(t *testing.T) {
code, stderr := runCheckCaptureStderr(t, []string{
"--repo", t.TempDir(),
"--cli-bin", "./lark-cli",
"--public-content-metadata", filepath.Join(t.TempDir(), "pr.json"),
})
if code != 2 {
t.Fatalf("exit code = %d, stderr=%s", code, stderr)
}
if !strings.Contains(stderr, "--public-content-metadata") || !strings.Contains(stderr, "--file") {
t.Fatalf("stderr = %s, want unsafe public content metadata path error", stderr)
}
}
func TestCheckReportsManifestReadErrorsWithFlagName(t *testing.T) {
dir := t.TempDir()
manifestPath := filepath.Join(dir, "command-manifest.json")
indexPath := filepath.Join(dir, "command-index.json")
if err := os.WriteFile(manifestPath, []byte(`{"schema_version":999,"commands":[]}`), 0o644); err != nil {
t.Fatal(err)
}
if err := manifest.WriteFile(indexPath, manifest.KindCommandIndex, manifest.Manifest{
SchemaVersion: 1,
Commands: []manifest.Command{{
Path: "drive file.comments create_v2",
CanonicalPath: "drive file-comments create-v2",
Source: manifest.SourceService,
Generated: true,
}},
}); err != nil {
t.Fatal(err)
}
code, stderr := runCheckCaptureStderr(t, []string{
"--repo", dir,
"--cli-bin", "./lark-cli",
"--manifest", manifestPath,
"--command-index", indexPath,
})
if code != 2 {
t.Fatalf("exit code = %d, stderr=%s", code, stderr)
}
if !strings.Contains(stderr, "--manifest:") {
t.Fatalf("stderr = %s", stderr)
}
}
func runCheckCaptureStderr(t *testing.T, args []string) (int, string) {
t.Helper()
original := os.Stderr
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
os.Stderr = w
code := runCheck(args)
if err := w.Close(); err != nil {
t.Fatal(err)
}
os.Stderr = original
data, err := io.ReadAll(r)
if err != nil {
t.Fatal(err)
}
return code, string(data)
}
@@ -0,0 +1,162 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package main
import (
"context"
"errors"
"flag"
"fmt"
"os"
"time"
"github.com/larksuite/cli/internal/qualitygate/facts"
"github.com/larksuite/cli/internal/qualitygate/report"
"github.com/larksuite/cli/internal/qualitygate/semantic"
)
func main() {
os.Exit(run(os.Args[1:]))
}
func run(args []string) int {
fs := flag.NewFlagSet("semantic-review", flag.ContinueOnError)
var repo, factsPath, reviewPath, waiversPath, decisionOut, markdownOut string
var block bool
fs.StringVar(&repo, "repo", ".", "repository root")
fs.StringVar(&factsPath, "facts", "", "facts.json path")
fs.StringVar(&reviewPath, "review-json", "", "optional precomputed review JSON")
fs.StringVar(&waiversPath, "waivers-file", "", "optional semantic waiver TSV file")
fs.StringVar(&decisionOut, "decision-out", "", "optional decision JSON output path")
fs.StringVar(&markdownOut, "markdown-out", "", "optional markdown output path")
fs.BoolVar(&block, "block", false, "exit 1 when gatekeeper finds blockers")
if err := fs.Parse(args); err != nil {
return 2
}
if factsPath == "" && fs.NArg() == 1 {
factsPath = fs.Arg(0)
}
if factsPath == "" {
fmt.Fprintln(os.Stderr, "semantic-review: --facts is required")
return 2
}
f, err := facts.ReadFile(factsPath)
if err != nil {
fmt.Fprintf(os.Stderr, "semantic-review: %v\n", err)
return 2
}
policy, waivers, waiverDiags, modelConfig, err := loadSemanticConfig(repo, waiversPath)
if err != nil {
fmt.Fprintf(os.Stderr, "semantic-review: %v\n", err)
decision := semantic.InfrastructureFailureDecision(err)
decision.BlockMode = block
_ = semantic.WriteDecision(decisionOut, decision)
_ = semantic.WriteMarkdown(markdownOut, decision)
return 0
}
if reviewPath == "" && !semantic.BuildInputView(f).HasReviewableFacts() {
decision := finalizeDecision(block, waiverDiags, semantic.Decision{})
if err := writeSemanticOutputs(decisionOut, markdownOut, decision); err != nil {
fmt.Fprintf(os.Stderr, "semantic-review: %v\n", err)
return 2
}
return decisionExitCode(decision)
}
review, err := semantic.LoadOrReviewWithConfig(context.Background(), f, reviewPath, modelConfig)
if err != nil {
fmt.Fprintf(os.Stderr, "semantic-review: %v\n", err)
decision := semantic.DegradedDecision(err)
switch {
case errors.Is(err, semantic.ErrReviewerUnavailable):
decision = semantic.SkippedDecision(err)
case errors.Is(err, semantic.ErrReviewerConfiguration):
decision = semantic.InfrastructureFailureDecision(err)
}
decision.BlockMode = block
_ = semantic.WriteDecision(decisionOut, decision)
_ = semantic.WriteMarkdown(markdownOut, decision)
return 0
}
decision := semantic.DecideWithWaivers(f, review, policy, waivers)
decision = finalizeDecision(block, waiverDiags, decision)
if err := writeSemanticOutputs(decisionOut, markdownOut, decision); err != nil {
fmt.Fprintf(os.Stderr, "semantic-review: %v\n", err)
return 2
}
return decisionExitCode(decision)
}
func finalizeDecision(block bool, waiverDiags []report.Diagnostic, decision semantic.Decision) semantic.Decision {
decision.BlockMode = block
if !block && len(decision.Blockers) > 0 {
for i := range decision.Blockers {
decision.Blockers[i].ReviewAction = semantic.ReviewActionObserve
}
decision.Warnings = append(decision.Warnings, decision.Blockers...)
decision.Blockers = nil
}
decision.SystemWarnings = append(diagnosticSystemWarnings(waiverDiags), decision.SystemWarnings...)
return decision
}
func writeSemanticOutputs(decisionOut, markdownOut string, decision semantic.Decision) error {
if err := semantic.WriteDecision(decisionOut, decision); err != nil {
return fmt.Errorf("write decision: %w", err)
}
if err := semantic.WriteMarkdown(markdownOut, decision); err != nil {
return fmt.Errorf("write markdown: %w", err)
}
return nil
}
func decisionExitCode(decision semantic.Decision) int {
if decision.BlockMode && len(decision.Blockers) > 0 {
return 1
}
return 0
}
func loadSemanticConfig(repo, waiversPath string) (semantic.Policy, semantic.Waivers, []report.Diagnostic, semantic.ModelConfig, error) {
policy, err := semantic.LoadPolicy(repo)
if err != nil {
return semantic.Policy{}, semantic.Waivers{}, nil, semantic.ModelConfig{}, fmt.Errorf("load policy: %w", err)
}
var (
waivers semantic.Waivers
waiverDiags []report.Diagnostic
)
if waiversPath != "" {
waivers, waiverDiags, err = semantic.LoadWaiversFile(waiversPath, now())
} else {
waivers, waiverDiags, err = semantic.LoadWaivers(repo, now())
}
if err != nil {
return semantic.Policy{}, semantic.Waivers{}, nil, semantic.ModelConfig{}, fmt.Errorf("load waivers: %w", err)
}
modelConfig, err := semantic.LoadModelConfig(repo)
if err != nil {
return semantic.Policy{}, semantic.Waivers{}, nil, semantic.ModelConfig{}, fmt.Errorf("load model config: %w", err)
}
return policy, waivers, waiverDiags, modelConfig, nil
}
var now = func() time.Time {
return time.Now()
}
func diagnosticSystemWarnings(diags []report.Diagnostic) []semantic.SystemWarning {
if len(diags) == 0 {
return nil
}
out := make([]semantic.SystemWarning, 0, len(diags))
for _, diag := range diags {
out = append(out, semantic.SystemWarning{
Severity: "minor",
Message: diag.Message,
SuggestedAction: diag.Suggestion,
})
}
return out
}
@@ -0,0 +1,384 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package main
import (
"encoding/json"
"os"
"path/filepath"
"strings"
"testing"
"github.com/larksuite/cli/internal/qualitygate/facts"
"github.com/larksuite/cli/internal/qualitygate/semantic"
)
func TestRunLoadsPolicyAndWaivers(t *testing.T) {
repo := t.TempDir()
writeSemanticConfig(t, repo, `{
"schema_version": 1,
"default_enforcement": "observe",
"block_categories": ["skill_quality"],
"rollout_groups": [{
"id": "changed-only",
"enforcement": "blocking",
"scope": {"changed_only": true},
"categories": ["skill_quality"],
"owner": "cli-owner",
"reason": "test rollout"
}]
}`, `{
"allowed": ["semantic-review-v1"],
"allowed_base_urls": ["https://ark.ap-southeast.bytepluses.com/api/v3"]
}`, "wiki-move\tskill_quality\tskill\tskills/lark-wiki/SKILL.md\t30\t\twiki-owner\tmigration\t2026-06-08\t2026-07-15\n")
factsPath := filepath.Join(t.TempDir(), "facts.json")
f := facts.Facts{
SchemaVersion: 1,
Skills: []facts.SkillFact{{
SourceFile: "skills/lark-wiki/SKILL.md",
Line: 30,
Changed: true,
ReferencesInvalidCommand: true,
}},
}
if err := f.WriteFile(factsPath); err != nil {
t.Fatalf("write facts: %v", err)
}
reviewPath := filepath.Join(t.TempDir(), "review.json")
if err := os.WriteFile(reviewPath, []byte(`{"verdict":"warn","findings":[{"category":"skill_quality","severity":"major","evidence":["facts.skills[0]"],"message":"bad","suggested_action":"fix"}]}`), 0o644); err != nil {
t.Fatalf("write review: %v", err)
}
decisionPath := filepath.Join(t.TempDir(), "decision.json")
code := run([]string{"--repo", repo, "--facts", factsPath, "--review-json", reviewPath, "--decision-out", decisionPath, "--block"})
if code != 0 {
t.Fatalf("run() = %d, want waived success", code)
}
decision := readDecision(t, decisionPath)
if len(decision.Blockers) != 0 || len(decision.Warnings) != 1 || decision.Warnings[0].WaiverID != "wiki-move" {
t.Fatalf("unexpected decision: %#v", decision)
}
if decision.Warnings[0].ReviewAction != semantic.ReviewActionConfirm {
t.Fatalf("review action = %q, want %q", decision.Warnings[0].ReviewAction, semantic.ReviewActionConfirm)
}
}
func TestRunLoadsWaiversFromOverrideFile(t *testing.T) {
repo := t.TempDir()
writeSemanticConfig(t, repo, `{
"schema_version": 1,
"default_enforcement": "observe",
"block_categories": ["error_hint"],
"rollout_groups": [{
"id": "changed-only",
"enforcement": "blocking",
"scope": {"changed_only": true},
"categories": ["error_hint"],
"owner": "cli-owner",
"reason": "test rollout"
}]
}`, `{
"allowed": ["semantic-review-v1"],
"allowed_base_urls": ["https://ark.ap-southeast.bytepluses.com/api/v3"]
}`, "")
factsPath := filepath.Join(t.TempDir(), "facts.json")
f := facts.Facts{
SchemaVersion: 1,
Errors: []facts.ErrorFact{{
File: "shortcuts/contact/contact_search_user.go",
Line: 199,
CommandPath: "contact +search-user",
Changed: true,
Boundary: true,
RequiredHint: true,
HintActionCount: 0,
Code: "validation",
}},
}
if err := f.WriteFile(factsPath); err != nil {
t.Fatalf("write facts: %v", err)
}
reviewPath := filepath.Join(t.TempDir(), "review.json")
if err := os.WriteFile(reviewPath, []byte(`{"verdict":"warn","findings":[{"category":"error_hint","severity":"major","evidence":["facts.errors[0]"],"message":"bad","suggested_action":"fix"}]}`), 0o644); err != nil {
t.Fatalf("write review: %v", err)
}
waiversPath := filepath.Join(t.TempDir(), "waivers.txt")
if err := os.WriteFile(waiversPath, []byte("semantic-error-hint-confirm\terror_hint\terror\tshortcuts/contact/contact_search_user.go\t199\t\tcli-owner\tsandbox confirm case\t2026-06-11\t2026-07-11\n"), 0o644); err != nil {
t.Fatalf("write override waivers: %v", err)
}
decisionPath := filepath.Join(t.TempDir(), "decision.json")
code := run([]string{"--repo", repo, "--facts", factsPath, "--review-json", reviewPath, "--waivers-file", waiversPath, "--decision-out", decisionPath, "--block"})
if code != 0 {
t.Fatalf("run() = %d, want waived success", code)
}
decision := readDecision(t, decisionPath)
if len(decision.Blockers) != 0 || len(decision.Warnings) != 1 {
t.Fatalf("unexpected decision: %#v", decision)
}
if decision.Warnings[0].ReviewAction != semantic.ReviewActionConfirm || decision.Warnings[0].WaiverID != "semantic-error-hint-confirm" {
t.Fatalf("override waiver was not used: %#v", decision.Warnings[0])
}
}
func TestRunCommentOnlyDowngradesPolicyBlockers(t *testing.T) {
repo := t.TempDir()
writeSemanticConfig(t, repo, `{
"schema_version": 1,
"default_enforcement": "observe",
"block_categories": ["skill_quality"],
"rollout_groups": [{
"id": "changed-only",
"enforcement": "blocking",
"scope": {"changed_only": true},
"categories": ["skill_quality"],
"owner": "cli-owner",
"reason": "test rollout"
}]
}`, `{
"allowed": ["semantic-review-v1"],
"allowed_base_urls": ["https://ark.ap-southeast.bytepluses.com/api/v3"]
}`, "")
factsPath := filepath.Join(t.TempDir(), "facts.json")
f := facts.Facts{
SchemaVersion: 1,
Skills: []facts.SkillFact{{
SourceFile: "skills/lark-wiki/SKILL.md",
Line: 30,
Changed: true,
ReferencesInvalidCommand: true,
}},
}
if err := f.WriteFile(factsPath); err != nil {
t.Fatalf("write facts: %v", err)
}
reviewPath := filepath.Join(t.TempDir(), "review.json")
if err := os.WriteFile(reviewPath, []byte(`{"verdict":"warn","findings":[{"category":"skill_quality","severity":"major","evidence":["facts.skills[0]"],"message":"bad","suggested_action":"fix"}]}`), 0o644); err != nil {
t.Fatalf("write review: %v", err)
}
decisionPath := filepath.Join(t.TempDir(), "decision.json")
code := run([]string{"--repo", repo, "--facts", factsPath, "--review-json", reviewPath, "--decision-out", decisionPath})
if code != 0 {
t.Fatalf("run() = %d, want success", code)
}
decision := readDecision(t, decisionPath)
if decision.BlockMode || len(decision.Blockers) != 0 || len(decision.Warnings) != 1 {
t.Fatalf("comment-only should warn only: %#v", decision)
}
if decision.Warnings[0].ReviewAction != semantic.ReviewActionObserve {
t.Fatalf("review action = %q, want %q", decision.Warnings[0].ReviewAction, semantic.ReviewActionObserve)
}
}
func TestRunWritesInfrastructureFailureDecisionForMissingPolicy(t *testing.T) {
repo := t.TempDir()
writeSemanticConfig(t, repo, "", `{
"allowed": ["semantic-review-v1"],
"allowed_base_urls": ["https://ark.ap-southeast.bytepluses.com/api/v3"]
}`, "")
factsPath := filepath.Join(t.TempDir(), "facts.json")
if err := (facts.Facts{SchemaVersion: 1}).WriteFile(factsPath); err != nil {
t.Fatalf("write facts: %v", err)
}
reviewPath := filepath.Join(t.TempDir(), "review.json")
if err := os.WriteFile(reviewPath, []byte(`{"verdict":"warn","findings":[]}`), 0o644); err != nil {
t.Fatalf("write review: %v", err)
}
decisionPath := filepath.Join(t.TempDir(), "decision.json")
code := run([]string{"--repo", repo, "--facts", factsPath, "--review-json", reviewPath, "--decision-out", decisionPath, "--block"})
if code != 0 {
t.Fatalf("run() = %d, want infrastructure handoff", code)
}
decision := readDecision(t, decisionPath)
if !decision.InfrastructureFailure || !decision.Degraded || !decision.BlockMode {
t.Fatalf("expected infrastructure blocking decision: %#v", decision)
}
}
func TestRunWritesSkippedDecisionForUnavailableReviewer(t *testing.T) {
t.Setenv("ARK_API_KEY", "")
t.Setenv("ARK_BASE_URL", "")
t.Setenv("ARK_MODEL", "")
repo := t.TempDir()
writeSemanticConfig(t, repo, `{
"schema_version": 1,
"default_enforcement": "observe",
"block_categories": ["skill_quality"]
}`, `{
"allowed": ["semantic-review-v1"],
"allowed_base_urls": ["https://ark.ap-southeast.bytepluses.com/api/v3"]
}`, "")
factsPath := filepath.Join(t.TempDir(), "facts.json")
f := facts.Facts{
SchemaVersion: 1,
Skills: []facts.SkillFact{{
SourceFile: "skills/lark-wiki/SKILL.md",
Line: 30,
Changed: true,
ReferencesInvalidCommand: true,
}},
}
if !semantic.BuildInputView(f).HasReviewableFacts() {
t.Fatal("test setup must contain reviewable facts")
}
if err := f.WriteFile(factsPath); err != nil {
t.Fatalf("write facts: %v", err)
}
decisionPath := filepath.Join(t.TempDir(), "decision.json")
code := run([]string{"--repo", repo, "--facts", factsPath, "--decision-out", decisionPath, "--block"})
if code != 0 {
t.Fatalf("run() = %d, want skipped handoff", code)
}
decision := readDecision(t, decisionPath)
if !decision.Skipped || decision.Degraded || decision.InfrastructureFailure || !decision.BlockMode {
t.Fatalf("expected skipped non-infrastructure decision: %#v", decision)
}
if len(decision.SystemWarnings) != 1 || len(decision.Warnings) != 0 || len(decision.Blockers) != 0 {
t.Fatalf("skipped decision should only carry system warnings: %#v", decision)
}
}
func TestRunShortCircuitsEmptySemanticInputWithoutReviewer(t *testing.T) {
t.Setenv("ARK_API_KEY", "")
t.Setenv("ARK_BASE_URL", "")
t.Setenv("ARK_MODEL", "")
repo := t.TempDir()
writeSemanticConfig(t, repo, `{
"schema_version": 1,
"default_enforcement": "observe",
"block_categories": ["skill_quality"]
}`, `{
"allowed": ["semantic-review-v1"],
"allowed_base_urls": ["https://ark.ap-southeast.bytepluses.com/api/v3"]
}`, "")
factsPath := filepath.Join(t.TempDir(), "facts.json")
f := facts.Facts{
SchemaVersion: 1,
Commands: []facts.CommandFact{{
Path: "service command 1",
Domain: "service",
Changed: true,
Source: "service",
}},
Outputs: []facts.OutputFact{{
Command: "service command 1",
Domain: "service",
Changed: true,
Source: "service",
IsList: true,
HasDefaultLimit: true,
HasDecisionField: true,
}},
}
if semantic.BuildInputView(f).HasReviewableFacts() {
t.Fatal("test setup must not contain reviewable facts")
}
if err := f.WriteFile(factsPath); err != nil {
t.Fatalf("write facts: %v", err)
}
decisionPath := filepath.Join(t.TempDir(), "decision.json")
markdownPath := filepath.Join(t.TempDir(), "semantic.md")
code := run([]string{"--repo", repo, "--facts", factsPath, "--decision-out", decisionPath, "--markdown-out", markdownPath, "--block"})
if code != 0 {
t.Fatalf("run() = %d, want clean pass", code)
}
decision := readDecision(t, decisionPath)
if decision.Skipped || decision.Degraded || decision.InfrastructureFailure || !decision.BlockMode {
t.Fatalf("expected non-degraded pass decision: %#v", decision)
}
if len(decision.SystemWarnings) != 0 || len(decision.Warnings) != 0 || len(decision.Blockers) != 0 {
t.Fatalf("empty semantic view should not produce findings: %#v", decision)
}
data, err := os.ReadFile(markdownPath)
if err != nil {
t.Fatalf("read markdown: %v", err)
}
markdown := string(data)
if !strings.Contains(markdown, "No semantic blockers.") {
t.Fatalf("markdown missing pass summary: %s", markdown)
}
if strings.Contains(strings.ToLower(markdown), "skipped") || strings.Contains(strings.ToLower(markdown), "degraded") {
t.Fatalf("markdown should not report semantic review as skipped/degraded: %s", markdown)
}
}
func TestRunWritesInfrastructureFailureDecisionForInvalidReviewerConfig(t *testing.T) {
t.Setenv("ARK_API_KEY", "test-key")
t.Setenv("ARK_BASE_URL", "")
t.Setenv("ARK_MODEL", "not-allowed-model")
repo := t.TempDir()
writeSemanticConfig(t, repo, `{
"schema_version": 1,
"default_enforcement": "observe",
"block_categories": ["skill_quality"]
}`, `{
"allowed": ["semantic-review-v1"],
"allowed_base_urls": ["https://ark.ap-southeast.bytepluses.com/api/v3"]
}`, "")
factsPath := filepath.Join(t.TempDir(), "facts.json")
f := facts.Facts{
SchemaVersion: 1,
Skills: []facts.SkillFact{{
SourceFile: "skills/lark-wiki/SKILL.md",
Line: 30,
Changed: true,
ReferencesInvalidCommand: true,
}},
}
if !semantic.BuildInputView(f).HasReviewableFacts() {
t.Fatal("test setup must contain reviewable facts")
}
if err := f.WriteFile(factsPath); err != nil {
t.Fatalf("write facts: %v", err)
}
decisionPath := filepath.Join(t.TempDir(), "decision.json")
code := run([]string{"--repo", repo, "--facts", factsPath, "--decision-out", decisionPath, "--block"})
if code != 0 {
t.Fatalf("run() = %d, want infrastructure handoff", code)
}
decision := readDecision(t, decisionPath)
if !decision.InfrastructureFailure || !decision.Degraded || decision.Skipped || !decision.BlockMode {
t.Fatalf("expected infrastructure failure decision: %#v", decision)
}
}
func writeSemanticConfig(t *testing.T, repo, policy, models, waivers string) {
t.Helper()
dir := filepath.Join(repo, "internal", "qualitygate", "config", "semantic")
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatalf("MkdirAll: %v", err)
}
if policy != "" {
if err := os.WriteFile(filepath.Join(dir, "policy.json"), []byte(policy), 0o644); err != nil {
t.Fatalf("write policy: %v", err)
}
}
if models != "" {
if err := os.WriteFile(filepath.Join(dir, "models.json"), []byte(models), 0o644); err != nil {
t.Fatalf("write models: %v", err)
}
}
if waivers != "" {
if err := os.WriteFile(filepath.Join(dir, "waivers.txt"), []byte(waivers), 0o644); err != nil {
t.Fatalf("write waivers: %v", err)
}
}
}
func readDecision(t *testing.T, path string) semantic.Decision {
t.Helper()
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read decision: %v", err)
}
var decision semantic.Decision
if err := json.Unmarshal(data, &decision); err != nil {
t.Fatalf("decode decision: %v", err)
}
return decision
}