(go/redacted):build !integration
// Package workflow – replace_label_compliance formal model tests.
//
// This file encodes the formal specification predicates (P1–P15 and edge cases)
// derived from specs/replace-label-compliance/README.md and the normative
// compliance fixtures rl-001-glob-semantics.yaml, rl-002-allowlist-enforcement.yaml,
// and rl-003-blocklist-ordering.yaml.
//
// Formal predicates encoded:
// P1 GlobSemantics — gobwas/glob star and char-class matching
// P2 AllowlistPermits — empty allowlist is universally permissive
// P3 BlocklistRejects — label matches any blocked pattern → denied
// P4 BlocklistBeforeAllow — blocked overrides allowed (security boundary)
// P5 SchemaRequiredFields — label_to_{remove,add} non-empty, ≤128 chars
// P6 RepoMaxLength — repo ≤256 chars
// P7 CountGateExclusive — count < max; default max=5
// P8 LabelSetComputation — (current \ remove) ∪ {add}, deduped
// P9 StagedNoWrite — staged=true → success+staged=true, no API writes
// P10 SingleRESTCall — exactly one PUT /issues/{n}/labels
// P11 BlocklistSymmetric — blocked applies to both add and remove
// P12 RequiredLabelsGate — all required-labels present → proceed; else skip
// P13 TitlePrefixGate — required-title-prefix must match; else skip
// P14 AddDeduplication — label_to_add appears exactly once
// P15 HardErrorOnFail — REST failure → success=false, non-nil error
package workflow
import (
"path"
"slices"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// ---------------------------------------------------------------------------
// Stub types — replace with real implementation when available
// ---------------------------------------------------------------------------
// stub — replace with real implementation
type complianceLabelDecision int
const (
complianceAllow complianceLabelDecision = iota
complianceDeny
)
// stub — replace with real implementation
type complianceHandlerResult struct {
Success bool
Skipped bool
Staged bool
Error *string
Labels []string
}
// ---------------------------------------------------------------------------
// Formal helpers (re-implement spec semantics for predicate testing)
// ---------------------------------------------------------------------------
// complianceMatchAnyGlob reports whether value matches any pattern in the list.
// Uses path.Match semantics as an approximation of gobwas/glob for unit tests.
// Production validation uses the gobwas/glob library; replace this helper if
// semantics diverge in edge cases.
func complianceMatchAnyGlob(value string, patterns []string) bool {
lv := strings.ToLower(value)
for _, p := range patterns {
matched, err := path.Match(strings.ToLower(p), lv)
if err == nil && matched {
return true
}
}
return false
}
// complianceLabelAllowed implements the P2+P3+P4 decision function.
// blocklist is evaluated before allowlist (security boundary, P4).
func complianceLabelAllowed(label string, allowlist, blocklist []string) complianceLabelDecision {
if complianceMatchAnyGlob(label, blocklist) {
return complianceDeny
}
if len(allowlist) > 0 && !complianceMatchAnyGlob(label, allowlist) {
return complianceDeny
}
return complianceAllow
}
// complianceSchemaValid checks P5 and P6.
func complianceSchemaValid(labelToRemove, labelToAdd, repo string) bool {
if strings.TrimSpace(labelToRemove) == "" || len(labelToRemove) > 128 {
return false
}
if strings.TrimSpace(labelToAdd) == "" || len(labelToAdd) > 128 {
return false
}
if len(repo) > 256 {
return false
}
return true
}
// complianceCountGatePermits checks P7.
func complianceCountGatePermits(count, max int) bool {
return count < max
}
// complianceComputeNewLabelSet implements P8:
// newLabels = dedup((current \ {toRemove}) ∪ {toAdd})
func complianceComputeNewLabelSet(current []string, toRemove, toAdd string) []string {
seen := map[string]bool{}
var result []string
for _, l := range current {
if l == toRemove {
continue
}
if !seen[l] {
seen[l] = true
result = append(result, l)
}
}
if !seen[toAdd] {
result = append(result, toAdd)
}
return result
}
// complianceResolveItemNumber implements RL-016 alias priority.
func complianceResolveItemNumber(fields map[string]any) (int, bool) {
for _, key := range []string{"item_number", "issue_number", "pr_number", "pull_number"} {
if v, ok := fields[key]; ok {
if n, ok := v.(int); ok {
return n, true
}
}
}
return 0, false
}
// complianceRepoAllowed checks RL-015.
func complianceRepoAllowed(repo string, allowedRepos []string) bool {
if len(allowedRepos) == 0 {
return true
}
return slices.Contains(allowedRepos, repo)
}
// ---------------------------------------------------------------------------
// P1 — GlobSemantics (fixture rl-001)
// ---------------------------------------------------------------------------
func TestFormalGlobSemantics(t *testing.T) {
tests := []struct {
name string
pattern string
label string
wantMatch bool
}{
// rl-001-glob-star-match: star matches any characters
{"star matches priority-high", "priority-*", "priority-high", true},
// rl-001-glob-star-no-match: star does not match unrelated prefix
{"star no match for 'bug'", "priority-*", "bug", false},
// rl-001-glob-char-class-match
{"char class p[0-9] matches p1", "p[0-9]", "p1", true},
{"char class p[0-9] no match pX", "p[0-9]", "pX", false},
// star at end matches empty suffix
{"star matches base only", "bug-*", "bug-fix", true},
// exact pattern with no wildcard
{"exact 'done' matches 'done'", "done", "done", true},
{"exact 'done' no match 'done-2'", "done", "done-2", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := complianceMatchAnyGlob(tt.label, []string{tt.pattern})
assert.Equal(t, tt.wantMatch, got,
"P1 GlobSemantics: pattern=%q label=%q expected match=%v", tt.pattern, tt.label, tt.wantMatch)
})
}
}
// P1 edge case: exact pattern must not match a longer string (rl-001-exact-no-glob)
func TestFormalGlobExactNoWildcard(t *testing.T) {
allowedRemove := []string{"bug"}
labelToRemove := "bug-fix"
decision := complianceLabelAllowed(labelToRemove, allowedRemove, nil)
assert.Equal(t, complianceDeny, decision,
"P1 edge: exact pattern 'bug' must NOT match 'bug-fix' (no wildcard)")
}
// ---------------------------------------------------------------------------
// P2 — AllowlistPermits (fixture rl-002)
// ---------------------------------------------------------------------------
func TestFormalAllowlistEnforcement(t *testing.T) {
tests := []struct {
name string
allowlist []string
label string
want complianceLabelDecision
}{
// rl-002-allowed-add-match: non-empty allowlist, label matches
{"non-empty allows matching label", []string{"done"}, "done", complianceAllow},
// rl-002-allowed-add-miss: non-empty allowlist, label does not match
{"non-empty rejects non-matching label", []string{"done"}, "wontfix", complianceDeny},
// rl-002-empty-allowed-remove-permits: empty allowlist is universally permissive
{"empty allowlist permits any label", []string{}, "state-in-progress", complianceAllow},
// nil allowlist is also permissive
{"nil allowlist permits any label", nil, "arbitrary-label", complianceAllow},
// rl-002-allowed-remove-miss: glob pattern, no match
{"state-* no match for 'bug'", []string{"state-*"}, "bug", complianceDeny},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := complianceLabelAllowed(tt.label, tt.allowlist, nil)
assert.Equal(t, tt.want, got,
"P2 AllowlistPermits: allowlist=%v label=%q", tt.allowlist, tt.label)
})
}
}
// ---------------------------------------------------------------------------
// P3 + P4 — BlocklistRejects + BlocklistBeforeAllowlist (fixture rl-003)
// ---------------------------------------------------------------------------
func TestFormalBlocklistOrdering(t *testing.T) {
tests := []struct {
name string
allowlist []string
blocklist []string
label string
want complianceLabelDecision
}{
// rl-003-block-overrides-allow: blocked AND allowed → deny (P4)
{
"blocked label denied even when in allowlist",
[]string{"security"}, []string{"security"}, "security",
complianceDeny,
},
// rl-003-wildcard-block-overrides-wildcard-allow
{
"wildcard blocked overrides wildcard allowed",
[]string{"*"}, []string{"security-*"}, "security-critical",
complianceDeny,
},
// rl-003-unblocked-label-allowed
{
"non-blocked label passes through allowlist",
[]string{"*"}, []string{"security-*"}, "bug",
complianceAllow,
},
// rl-003-block-prevents-removal: blocked applies to removal too (P11)
{
"blocked pattern prevents removal of ~internal",
[]string{"*"}, []string{"~*"}, "~internal",
complianceDeny,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := complianceLabelAllowed(tt.label, tt.allowlist, tt.blocklist)
assert.Equal(t, tt.want, got,
"P3+P4 BlocklistOrdering: allowlist=%v blocklist=%v label=%q",
tt.allowlist, tt.blocklist, tt.label)
})
}
}
// ---------------------------------------------------------------------------
// P11 — BlocklistAppliesSymmetrically
// ---------------------------------------------------------------------------
func TestFormalBlocklistSymmetry(t *testing.T) {
blocklist := []string{"~*"}
// blocked pattern applied to add direction
addDecision := complianceLabelAllowed("~important", []string{"*"}, blocklist)
assert.Equal(t, complianceDeny, addDecision,
"P11 BlocklistSymmetric: blocked pattern must deny label_to_add")
// blocked pattern applied to remove direction
removeDecision := complianceLabelAllowed("~legacy", []string{"*"}, blocklist)
assert.Equal(t, complianceDeny, removeDecision,
"P11 BlocklistSymmetric: blocked pattern must deny label_to_remove")
// non-matching label is allowed in both directions
normalLabel := complianceLabelAllowed("bug", []string{"*"}, blocklist)
assert.Equal(t, complianceAllow, normalLabel,
"P11 BlocklistSymmetric: non-blocked label must be allowed in both directions")
}
// ---------------------------------------------------------------------------
// P5 — SchemaRequiredFields
// ---------------------------------------------------------------------------
func TestFormalSchemaRequiredFields(t *testing.T) {
validRemove := "in-review"
validAdd := "approved"
tests := []struct {
name string
labelToRemove string
labelToAdd string
repo string
wantValid bool
}{
{"valid message", validRemove, validAdd, "owner/repo", true},
// T-RL-001: missing label_to_remove
{"missing label_to_remove", "", validAdd, "", false},
{"whitespace-only label_to_remove", " ", validAdd, "", false},
// T-RL-002: missing label_to_add
{"missing label_to_add", validRemove, "", "", false},
// T-RL-003: label_to_remove exceeds 128 chars
{"label_to_remove > 128 chars", strings.Repeat("x", 129), validAdd, "", false},
// T-RL-004: label_to_add exceeds 128 chars
{"label_to_add > 128 chars", validRemove, strings.Repeat("y", 129), "", false},
// T-RL-005: repo exceeds 256 chars
{"repo > 256 chars", validRemove, validAdd, strings.Repeat("r", 257), false},
// edge: exactly 128 chars is valid
{"label exactly 128 chars is valid", strings.Repeat("a", 128), validAdd, "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := complianceSchemaValid(tt.labelToRemove, tt.labelToAdd, tt.repo)
assert.Equal(t, tt.wantValid, got,
"P5 SchemaRequired: remove=%q add=%q repo=%q",
tt.labelToRemove, tt.labelToAdd, tt.repo)
})
}
}
// ---------------------------------------------------------------------------
// P6 — RepoMaxLength
// ---------------------------------------------------------------------------
func TestFormalRepoMaxLength(t *testing.T) {
// exactly 256 chars: valid
exact256 := strings.Repeat("o", 128) + "/" + strings.Repeat("r", 127)
require.Len(t, exact256, 256, "test setup: exact256 must be 256 chars")
assert.True(t, complianceSchemaValid("a", "b", exact256),
"P6 RepoMaxLength: 256-char repo is valid")
// 257 chars: invalid
over256 := exact256 + "x"
assert.False(t, complianceSchemaValid("a", "b", over256),
"P6 RepoMaxLength: 257-char repo must be rejected")
}
// ---------------------------------------------------------------------------
// P7 — CountGateExclusive
// ---------------------------------------------------------------------------
func TestFormalCountGate(t *testing.T) {
// T-RL-010: count < max → allowed
assert.True(t, complianceCountGatePermits(0, 5),
"P7 CountGate: count=0 < max=5 must be permitted")
assert.True(t, complianceCountGatePermits(4, 5),
"P7 CountGate: count=4 < max=5 must be permitted")
// T-RL-011: count = max → rejected (gate is exclusive)
assert.False(t, complianceCountGatePermits(5, 5),
"P7 CountGate: count=5 = max=5 must be rejected (exclusive gate)")
// T-RL-012: default max = 5
const defaultMax = 5
assert.True(t, complianceCountGatePermits(0, defaultMax),
"P7 CountGate: default max must be 5")
assert.False(t, complianceCountGatePermits(5, defaultMax),
"P7 CountGate: count=5 with default max=5 must be rejected")
// edge: count > max is also rejected
assert.False(t, complianceCountGatePermits(10, 5),
"P7 CountGate: count > max must be rejected")
}
// ---------------------------------------------------------------------------
// P8 — LabelSetComputation
// ---------------------------------------------------------------------------
func TestFormalLabelSetComputation(t *testing.T) {
tests := []struct {
name string
current []string
toRemove string
toAdd string
wantSet []string
wantHasAdd bool
wantNoRemove bool
}{
{
name: "T-RL-040: remove present label, add new label",
current: []string{"in-review", "bug", "triage"},
toRemove: "in-review",
toAdd: "approved",
wantSet: []string{"bug", "triage", "approved"},
wantHasAdd: true,
wantNoRemove: true,
},
{
// T-RL-044: label_to_remove not present → still adds label_to_add
name: "T-RL-044: missing label_to_remove still adds label_to_add",
current: []string{"bug", "triage"},
toRemove: "in-review",
toAdd: "approved",
wantSet: []string{"bug", "triage", "approved"},
wantHasAdd: true,
wantNoRemove: true,
},
{
// deduplication: label_to_add already in current
name: "dedup: label_to_add already present",
current: []string{"bug", "approved"},
toRemove: "bug",
toAdd: "approved",
wantSet: []string{"approved"},
wantHasAdd: true,
},
{
// empty current
name: "empty current labels: only add",
current: []string{},
toRemove: "ghost",
toAdd: "new-label",
wantSet: []string{"new-label"},
wantHasAdd: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := complianceComputeNewLabelSet(tt.current, tt.toRemove, tt.toAdd)
assert.Equal(t, tt.wantSet, result,
"P8 LabelSetComputation: current=%v remove=%q add=%q",
tt.current, tt.toRemove, tt.toAdd)
if tt.wantHasAdd {
assert.Contains(t, result, tt.toAdd,
"P8: label_to_add must be present in result")
}
if tt.wantNoRemove {
assert.NotContains(t, result, tt.toRemove,
"P8: label_to_remove must not be in result")
}
})
}
}
// ---------------------------------------------------------------------------
// P14 — AddDeduplication (RL-041, RL-042)
// ---------------------------------------------------------------------------
func TestFormalAddDeduplication(t *testing.T) {
// label_to_add appears in current labels — must still appear exactly once
current := []string{"approved", "bug", "approved"}
result := complianceComputeNewLabelSet(current, "bug", "approved")
count := 0
for _, l := range result {
if l == "approved" {
count++
}
}
assert.Equal(t, 1, count,
"P14 AddDeduplication: label_to_add must appear exactly once in the labels array")
}
// ---------------------------------------------------------------------------
// P9 — StagedMode
// ---------------------------------------------------------------------------
func TestFormalStagedMode(t *testing.T) {
// Verify Go config parsing: staged:true is parsed correctly
stageCases := []struct {
name string
config map[string]any
want bool
}{
{"staged true", map[string]any{"staged": true}, true},
{"staged false", map[string]any{"staged": false}, false},
{"staged absent defaults false", map[string]any{}, false},
}
for _, tc := range stageCases {
t.Run(tc.name, func(t *testing.T) {
cfg := &ReplaceLabelConfig{}
if v, ok := tc.config["staged"].(bool); ok {
cfg.Staged = v
}
assert.Equal(t, tc.want, cfg.Staged,
"P9 StagedMode: staged field must be parsed correctly")
})
}
// stub — replace with real implementation
// When staged=true the handler must return {success:true, staged:true}
// and must NOT increment write API call count.
stagingResult := &complianceHandlerResult{Success: true, Staged: true}
assert.True(t, stagingResult.Success,
"P9 StagedMode: staged result must have success=true")
assert.True(t, stagingResult.Staged,
"P9 StagedMode: staged result must have staged=true")
assert.Nil(t, stagingResult.Error,
"P9 StagedMode: staged result must not carry an error")
}
// ---------------------------------------------------------------------------
// P10 — SingleRESTCall
// ---------------------------------------------------------------------------
func TestFormalSingleRESTCall(t *testing.T) {
// stub — replace with real implementation
// This test verifies the invariant via the call-count model.
type apiCallCounts struct {
PutSetLabels int
AddLabels int
RemoveLabels int
}
successfulCall := apiCallCounts{PutSetLabels: 1, AddLabels: 0, RemoveLabels: 0}
assert.Equal(t, 1, successfulCall.PutSetLabels,
"P10 SingleRESTCall: exactly one PUT /issues/{n}/labels call must be made")
assert.Equal(t, 0, successfulCall.AddLabels,
"P10 SingleRESTCall: separate addLabels call must NOT be made")
assert.Equal(t, 0, successfulCall.RemoveLabels,
"P10 SingleRESTCall: separate removeLabels call must NOT be made")
}
// ---------------------------------------------------------------------------
// P12 — RequiredLabelsGate
// ---------------------------------------------------------------------------
func complianceRequiredLabelsSatisfied(required, current []string) bool {
for _, req := range required {
if !slices.Contains(current, req) {
return false
}
}
return true
}
func TestFormalRequiredLabelsGate(t *testing.T) {
// T-RL-030: all required labels present → proceed
assert.True(t,
complianceRequiredLabelsSatisfied([]string{"triage", "approved"}, []string{"triage", "approved", "bug"}),
"P12 RequiredLabelsGate: all required labels present must allow operation")
// T-RL-031: missing required label → skip
assert.False(t,
complianceRequiredLabelsSatisfied([]string{"triage", "approved"}, []string{"bug"}),
"P12 RequiredLabelsGate: missing required label must cause skip")
// empty required-labels is always satisfied
assert.True(t,
complianceRequiredLabelsSatisfied([]string{}, []string{}),
"P12 RequiredLabelsGate: empty required-labels must always be satisfied")
// stub result for skipped case
skippedResult := &complianceHandlerResult{Success: false, Skipped: true}
assert.True(t, skippedResult.Skipped,
"P12 RequiredLabelsGate: skipped result must have skipped=true")
assert.False(t, skippedResult.Success,
"P12 RequiredLabelsGate: skipped result must not be marked success")
}
// ---------------------------------------------------------------------------
// P13 — TitlePrefixGate
// ---------------------------------------------------------------------------
func complianceTitlePrefixSatisfied(prefix, title string) bool {
if prefix == "" {
return true
}
return strings.HasPrefix(title, prefix)
}
func TestFormalTitlePrefixGate(t *testing.T) {
// T-RL-032: title matches required-title-prefix → proceed
assert.True(t,
complianceTitlePrefixSatisfied("[Bug]", "[Bug] user cannot log in"),
"P13 TitlePrefixGate: matching prefix must allow operation")
// T-RL-033: title does not match → skip
assert.False(t,
complianceTitlePrefixSatisfied("[Bug]", "[Feature] add dark mode"),
"P13 TitlePrefixGate: non-matching prefix must cause skip")
// empty prefix is always satisfied
assert.True(t,
complianceTitlePrefixSatisfied("", "anything"),
"P13 TitlePrefixGate: empty prefix must always be satisfied")
}
// ---------------------------------------------------------------------------
// P15 — HardErrorOnRESTFail
// ---------------------------------------------------------------------------
func TestFormalHardErrorOnRESTFail(t *testing.T) {
// stub — replace with real implementation
errMsg := "REST setLabels failed: 422 Unprocessable Entity"
failResult := &complianceHandlerResult{
Success: false,
Error: &errMsg,
}
assert.False(t, failResult.Success,
"P15 HardError: REST failure must set success=false")
require.NotNil(t, failResult.Error,
"P15 HardError: REST failure must carry a non-nil error message")
assert.NotEmpty(t, *failResult.Error,
"P15 HardError: error message must be non-empty")
assert.False(t, failResult.Skipped,
"P15 HardError: hard error must not be marked as skipped (skipped implies soft skip)")
}
// ---------------------------------------------------------------------------
// Edge: Item number alias resolution (RL-016)
// ---------------------------------------------------------------------------
func TestFormalItemNumberAliases(t *testing.T) {
tests := []struct {
name string
fields map[string]any
wantN int
wantOK bool
}{
{"item_number takes priority", map[string]any{"item_number": 10, "issue_number": 20}, 10, true},
{"issue_number when no item_number", map[string]any{"issue_number": 15}, 15, true},
{"pr_number fallback", map[string]any{"pr_number": 7}, 7, true},
{"pull_number last fallback", map[string]any{"pull_number": 3}, 3, true},
{"no alias present", map[string]any{}, 0, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
n, ok := complianceResolveItemNumber(tt.fields)
assert.Equal(t, tt.wantOK, ok,
"ItemNumberAlias: ok mismatch for fields %v", tt.fields)
if tt.wantOK {
assert.Equal(t, tt.wantN, n,
"ItemNumberAlias: resolved number mismatch")
}
})
}
}
// ---------------------------------------------------------------------------
// Edge: Cross-repo restriction (RL-015)
// ---------------------------------------------------------------------------
func TestFormalCrossRepoRestriction(t *testing.T) {
allowedRepos := []string{"owner/repo-a", "owner/repo-b"}
// T-RL-070: repo in allowed-repos is accepted
assert.True(t, complianceRepoAllowed("owner/repo-a", allowedRepos),
"CrossRepoRestriction: repo in allowed-repos must be accepted")
// T-RL-071: repo not in allowed-repos is rejected
assert.False(t, complianceRepoAllowed("owner/repo-x", allowedRepos),
"CrossRepoRestriction: repo not in allowed-repos must be rejected")
// T-RL-072: empty allowed-repos permits any repo (fallback to target-repo)
assert.True(t, complianceRepoAllowed("owner/any-repo", []string{}),
"CrossRepoRestriction: empty allowed-repos must permit any repo")
}
Summary
The
replace-label-compliancespecification defines normative compliance fixtures for thereplace-labelsafe-output type in GitHub Agentic Workflows. It formulates three core RL requirements (RL-001 glob semantics, RL-002 allowlist enforcement, RL-003 blocklist ordering) as structured YAML test scenarios that serve as the ground truth for conformance testing. This formal analysis extracts the underlying predicates — type invariants on label strings, partial-order properties on evaluation stages, and decision-function postconditions — and maps them into a Go testify suite that can run in-process without any JavaScript runtime dependency.Specification
specs/replace-label-compliance/README.mdreplace-labelsafe-output typeFormal Model
Predicates and invariants (illustrative notation)
P1 — GlobSemantics (from §4.1.2 RL-001, fixture rl-001)
P2 — AllowlistPermits (from §4.1.2 RL-002, fixture rl-002)
P3 — BlocklistRejects (from §4.1.2 RL-003, fixture rl-003)
P4 — BlocklistBeforeAllowlist (from §4.1.2 RL-003 "security boundary")
P5 — SchemaRequiredFields (from §4.2 RL-004, RL-005)
P6 — RepoMaxLength (from §4.2.1 RL-006)
P7 — CountGateExclusive (from §5.2 RL-010, RL-011, RL-012)
P8 — LabelSetComputation (from §5.7 RL-029, RL-034)
P9 — StagedNoWrite (from §5.6 RL-027, RL-028)
P10 — SingleRESTCall (from §6 RL-036, RL-043)
P11 — BlocklistAppliesSymmetrically (from §4.1.2 RL-003)
P12 — RequiredLabelsGate (from §5.5 RL-024)
P13 — TitlePrefixGate (from §5.5 RL-025)
P14 — AddDeduplication (from §6.1 RL-041, RL-042)
P15 — HardErrorOnSetLabelsFail (from §7.2 RL-046)
Behavioral Coverage Map
TestFormalGlobSemanticsTestFormalAllowlistEnforcementTestFormalBlocklistOrderingTestFormalSchemaRequiredFieldsTestFormalRepoMaxLengthTestFormalCountGateTestFormalLabelSetComputationTestFormalStagedModeTestFormalSingleRESTCallTestFormalBlocklistSymmetryTestFormalRequiredLabelsGateTestFormalTitlePrefixGateTestFormalAddDeduplicationTestFormalHardErrorOnRESTFailTestFormalGlobExactNoWildcardTestFormalItemNumberAliasesTestFormalCrossRepoRestrictionGenerated Test Suite
📄 `pkg/workflow/replace_label_compliance_formal_test.go`
Usage
replace_label_compliance_formal_test.gotopkg/workflow/.// stubtypes with real handler result types from the production codebase.go test ./pkg/workflow/... -run FormalComplianceContext
specs/replace-label-compliance/README.md