Skip to content

Commit 5054185

Browse files
Merge pull request #364 from gastownhall/fix/routed-to-metadata-audit-complete
Use gc.routed_to for dispatched work routing
2 parents edee912 + 9340182 commit 5054185

25 files changed

Lines changed: 345 additions & 174 deletions

File tree

cmd/gc/build_desired_state.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ func collectAssignedWorkBeads(
423423

424424
func appendAssignedUnique(dst *[]beads.Bead, beadList []beads.Bead, seen map[string]struct{}) {
425425
for _, b := range beadList {
426-
if strings.TrimSpace(b.Assignee) == "" && strings.TrimSpace(b.Metadata["gc.routed_to"]) == "" {
426+
if strings.TrimSpace(b.Assignee) == "" && strings.TrimSpace(b.Metadata["gc.routed_to"]) == "" && !hasPoolLabel(b) {
427427
continue
428428
}
429429
if _, ok := seen[b.ID]; ok {
@@ -434,6 +434,15 @@ func appendAssignedUnique(dst *[]beads.Bead, beadList []beads.Bead, seen map[str
434434
}
435435
}
436436

437+
func hasPoolLabel(b beads.Bead) bool {
438+
for _, l := range b.Labels {
439+
if strings.HasPrefix(l, "pool:") {
440+
return true
441+
}
442+
}
443+
return false
444+
}
445+
437446
func controlDispatcherOnlyConfig(cfg *config.City) *config.City {
438447
if cfg == nil {
439448
return nil

cmd/gc/cmd_convoy_dispatch.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ func graphFallbackBindingForBead(source beads.Bead, store beads.Store, cityName
290290

291291
binding := graphRouteBinding{qualifiedName: agentCfg.QualifiedName()}
292292
if isMultiSessionCfgAgent(&agentCfg) {
293-
binding.label = "pool:" + agentCfg.QualifiedName()
293+
binding.metadataOnly = true
294294
return binding, nil
295295
}
296296
if source.Assignee != "" {

cmd/gc/cmd_convoy_dispatch_test.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,15 +274,11 @@ func TestDecorateDynamicFragmentRecipePreservesPoolFallbackAndScopeMetadata(t *t
274274
if review.Metadata["gc.routed_to"] != "frontend/reviewer" {
275275
t.Fatalf("review gc.routed_to = %q, want frontend/reviewer", review.Metadata["gc.routed_to"])
276276
}
277-
foundPoolLabel := false
278277
for _, label := range review.Labels {
279278
if label == "pool:frontend/reviewer" {
280-
foundPoolLabel = true
279+
t.Fatalf("review labels = %#v, should not contain legacy pool label", review.Labels)
281280
}
282281
}
283-
if !foundPoolLabel {
284-
t.Fatalf("review labels = %#v, want pool label", review.Labels)
285-
}
286282
if review.Metadata["gc.scope_ref"] != "body" {
287283
t.Fatalf("review gc.scope_ref = %q, want body", review.Metadata["gc.scope_ref"])
288284
}

cmd/gc/cmd_order.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func newOrderListCmd(stdout, stderr io.Writer) *cobra.Command {
5151
return &cobra.Command{
5252
Use: "list",
5353
Short: "List available orders",
54-
Long: `List all available orders with their gate type, schedule, and target pool.
54+
Long: `List all available orders with their gate type, schedule, and target.
5555
5656
Scans formula layers for formulas that have order metadata
5757
(gate, interval, schedule, check, pool).`,
@@ -73,7 +73,7 @@ func newOrderShowCmd(stdout, stderr io.Writer) *cobra.Command {
7373
Long: `Display detailed information about a named order.
7474
7575
Shows the order name, description, formula reference, gate type,
76-
scheduling parameters, check command, target pool, and source file.
76+
scheduling parameters, check command, target, and source file.
7777
Use --rig to disambiguate same-name orders in different rigs.`,
7878
Args: cobra.ExactArgs(1),
7979
RunE: func(_ *cobra.Command, args []string) error {
@@ -95,7 +95,7 @@ func newOrderRunCmd(stdout, stderr io.Writer) *cobra.Command {
9595
Long: `Execute an order manually, bypassing its gate conditions.
9696
9797
Instantiates a wisp from the order's formula and routes it to the
98-
target pool (if configured). Useful for testing orders or triggering
98+
configured target (if any). Useful for testing orders or triggering
9999
them outside their normal schedule.
100100
Use --rig to disambiguate same-name orders in different rigs.`,
101101
Args: cobra.ExactArgs(1),
@@ -303,9 +303,9 @@ func doOrderList(aa []orders.Order, stdout io.Writer) int {
303303

304304
hasRig := anyOrderHasRig(aa)
305305
if hasRig {
306-
fmt.Fprintf(stdout, "%-20s %-8s %-12s %-15s %-15s %s\n", "NAME", "TYPE", "GATE", "INTERVAL/SCHED", "RIG", "POOL") //nolint:errcheck
306+
fmt.Fprintf(stdout, "%-20s %-8s %-12s %-15s %-15s %s\n", "NAME", "TYPE", "GATE", "INTERVAL/SCHED", "RIG", "TARGET") //nolint:errcheck
307307
} else {
308-
fmt.Fprintf(stdout, "%-20s %-8s %-12s %-15s %s\n", "NAME", "TYPE", "GATE", "INTERVAL/SCHED", "POOL") //nolint:errcheck
308+
fmt.Fprintf(stdout, "%-20s %-8s %-12s %-15s %s\n", "NAME", "TYPE", "GATE", "INTERVAL/SCHED", "TARGET") //nolint:errcheck
309309
}
310310
for _, a := range aa {
311311
typ := "formula"
@@ -394,7 +394,7 @@ func doOrderShow(aa []orders.Order, name, rig string, stdout, stderr io.Writer)
394394
w(fmt.Sprintf("On: %s", a.On))
395395
}
396396
if a.Pool != "" {
397-
w(fmt.Sprintf("Pool: %s", a.Pool))
397+
w(fmt.Sprintf("Target: %s", a.Pool))
398398
}
399399
w(fmt.Sprintf("Source: %s", a.Source))
400400
return 0
@@ -424,7 +424,7 @@ func cmdOrderRun(name, rig string, stdout, stderr io.Writer) int {
424424

425425
// doOrderRun executes an order manually: instantiates a wisp from the
426426
// order's formula (or runs exec script directly) and routes it to the
427-
// target pool.
427+
// configured target.
428428
func doOrderRun(aa []orders.Order, name, rig, cityPath string, runner SlingRunner, store beads.Store, ep events.Provider, stdout, stderr io.Writer) int {
429429
a, ok := findOrder(aa, name, rig)
430430
if !ok {
@@ -482,15 +482,16 @@ func doOrderRun(aa []orders.Order, name, rig, cityPath string, runner SlingRunne
482482
}
483483
rootID := cookResult.RootID
484484

485-
// Label with order-run:<scopedName> for tracking, plus pool routing if specified.
486-
// For event gates, also add order:<scopedName> and seq:<headSeq> for cursor tracking.
485+
// Label with order-run:<scopedName> for tracking, plus root routing metadata
486+
// when a target is configured. For event gates, also add order:<scopedName>
487+
// and seq:<headSeq> for cursor tracking.
487488
routeCmd := fmt.Sprintf("bd update %s --add-label=order-run:%s", rootID, scoped)
488489
if a.Gate == "event" && ep != nil {
489490
routeCmd += fmt.Sprintf(" --add-label=order:%s --add-label=seq:%d", scoped, headSeq)
490491
}
491492
if a.Pool != "" {
492493
pool := qualifyPool(a.Pool, a.Rig)
493-
routeCmd += fmt.Sprintf(" --add-label=pool:%s", pool)
494+
routeCmd += fmt.Sprintf(" --set-metadata gc.routed_to=%s", pool)
494495
}
495496
if _, err := runner("", routeCmd, nil); err != nil {
496497
fmt.Fprintf(stderr, "gc order run: labeling wisp: %v\n", err) //nolint:errcheck // best-effort stderr
@@ -499,7 +500,7 @@ func doOrderRun(aa []orders.Order, name, rig, cityPath string, runner SlingRunne
499500

500501
fmt.Fprintf(stdout, "Order %q executed: wisp %s", name, rootID) //nolint:errcheck
501502
if a.Pool != "" {
502-
fmt.Fprintf(stdout, " → pool:%s", a.Pool) //nolint:errcheck
503+
fmt.Fprintf(stdout, " → gc.routed_to=%s", qualifyPool(a.Pool, a.Rig)) //nolint:errcheck
503504
}
504505
fmt.Fprintln(stdout) //nolint:errcheck
505506
return 0

cmd/gc/cmd_order_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,12 @@ func TestOrderRun(t *testing.T) {
340340
if len(calls) != 1 {
341341
t.Fatalf("got %d runner calls, want 1: %v", len(calls), calls)
342342
}
343-
// Should include both order-run label and pool label in a single bd update.
343+
// Should include both order-run tracking and routed_to metadata in a single bd update.
344344
if !strings.Contains(calls[0], "--add-label=order-run:digest") {
345345
t.Errorf("call[0] = %q, want --add-label=order-run:digest", calls[0])
346346
}
347-
if !strings.Contains(calls[0], "--add-label=pool:dog") {
348-
t.Errorf("call[0] = %q, want --add-label=pool:dog", calls[0])
347+
if !strings.Contains(calls[0], "--set-metadata gc.routed_to=dog") {
348+
t.Errorf("call[0] = %q, want --set-metadata gc.routed_to=dog", calls[0])
349349
}
350350
}
351351

@@ -375,9 +375,9 @@ func TestOrderRunNoPool(t *testing.T) {
375375
if !strings.Contains(calls[0], "--add-label=order-run:cleanup") {
376376
t.Errorf("call[0] = %q, want --add-label=order-run:cleanup", calls[0])
377377
}
378-
// Should NOT contain pool label.
379-
if strings.Contains(calls[0], "--add-label=pool:") {
380-
t.Errorf("call[0] = %q, should not contain pool label", calls[0])
378+
// Should NOT contain routed_to metadata.
379+
if strings.Contains(calls[0], "--set-metadata gc.routed_to=") {
380+
t.Errorf("call[0] = %q, should not contain routed_to metadata", calls[0])
381381
}
382382
// Verify wisp ID appears in stdout (MemStore generates gc-N IDs).
383383
if !strings.Contains(stdout.String(), "gc-1") {
@@ -722,8 +722,8 @@ func TestOrderRunRigQualifiesPool(t *testing.T) {
722722
if !strings.Contains(calls[0], "--add-label=order-run:db-health:rig:demo-repo") {
723723
t.Errorf("call[0] = %q, want --add-label=order-run:db-health:rig:demo-repo", calls[0])
724724
}
725-
// Auto-qualified pool.
726-
if !strings.Contains(calls[0], "--add-label=pool:demo-repo/polecat") {
727-
t.Errorf("call[0] = %q, want --add-label=pool:demo-repo/polecat", calls[0])
725+
// Auto-qualified routed_to target.
726+
if !strings.Contains(calls[0], "--set-metadata gc.routed_to=demo-repo/polecat") {
727+
t.Errorf("call[0] = %q, want --set-metadata gc.routed_to=demo-repo/polecat", calls[0])
728728
}
729729
}

cmd/gc/cmd_sling.go

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -949,9 +949,10 @@ func slingFormulaUsesTargetBranch(formula string) bool {
949949
}
950950

951951
// resolveSlingEnv returns extra env vars for the sling command.
952-
// For fixed (non-pool) agents, resolves the target's session name from
953-
// the bead store and returns it as GC_SLING_TARGET. Pool agents don't
954-
// need this — they use label-based dispatch.
952+
// For fixed single-session agents, resolves the target's session name from
953+
// the bead store and returns it as GC_SLING_TARGET. Default routing uses
954+
// gc.routed_to metadata for all agents, but custom sling_query templates may
955+
// still rely on the resolved concrete session target.
955956
func resolveSlingEnv(a config.Agent, deps slingDeps) map[string]string {
956957
if isMultiSessionCfgAgent(&a) {
957958
return nil
@@ -1121,7 +1122,7 @@ func decorateGraphWorkflowRecipe(recipe *formula.Recipe, routeVars map[string]st
11211122
if sessionName != "" {
11221123
defaultRoute.sessionName = sessionName
11231124
} else {
1124-
defaultRoute.label = "pool:" + routedTo
1125+
defaultRoute.metadataOnly = true
11251126
}
11261127
routingRigContext := graphRouteRigContext(defaultRoute.qualifiedName)
11271128
controlRoute, err := controlDispatcherBinding(store, cityName, cfg, routingRigContext)
@@ -1213,7 +1214,7 @@ func workflowStoreRefForDir(storeDir, cityPath, cityName string, cfg *config.Cit
12131214
type graphRouteBinding struct {
12141215
qualifiedName string
12151216
sessionName string
1216-
label string
1217+
metadataOnly bool
12171218
}
12181219

12191220
func resolveGraphStepBinding(stepID string, stepByID map[string]*formula.RecipeStep, stepAlias map[string]string, depsByStep map[string][]string, cache map[string]graphRouteBinding, resolving map[string]bool, fallback graphRouteBinding, rigContext string, store beads.Store, cityName string, cfg *config.City) (graphRouteBinding, error) {
@@ -1327,7 +1328,7 @@ func resolveGraphStepBindingWithVars(stepID string, stepByID map[string]*formula
13271328
}
13281329
binding := graphRouteBinding{qualifiedName: agentCfg.QualifiedName()}
13291330
if isMultiSessionCfgAgent(&agentCfg) {
1330-
binding.label = "pool:" + agentCfg.QualifiedName()
1331+
binding.metadataOnly = true
13311332
cache[stepID] = binding
13321333
return binding, nil
13331334
}
@@ -1366,15 +1367,6 @@ func graphRouteRigContext(route string) string {
13661367
return route[:idx]
13671368
}
13681369

1369-
func appendUniqueString(in []string, value string) []string {
1370-
for _, existing := range in {
1371-
if existing == value {
1372-
return in
1373-
}
1374-
}
1375-
return append(in, value)
1376-
}
1377-
13781370
func shouldPromoteWorkflowLaunchStatus(status string) bool {
13791371
switch strings.ToLower(strings.TrimSpace(status)) {
13801372
case "", "open", "ready", "todo", "triage", "backlog":
@@ -1461,6 +1453,9 @@ func checkBeadState(q BeadQuerier, beadID string, a config.Agent) beadCheckResul
14611453
if b.Assignee != "" {
14621454
warnings = append(warnings, fmt.Sprintf("warning: bead %s already assigned to %q", beadID, b.Assignee))
14631455
}
1456+
if routedTo := strings.TrimSpace(b.Metadata["gc.routed_to"]); routedTo != "" {
1457+
warnings = append(warnings, fmt.Sprintf("warning: bead %s already routed to %q", beadID, routedTo))
1458+
}
14641459
for _, l := range b.Labels {
14651460
if strings.HasPrefix(l, "pool:") {
14661461
warnings = append(warnings, fmt.Sprintf("warning: bead %s already has pool label %q", beadID, l))
@@ -1470,8 +1465,20 @@ func checkBeadState(q BeadQuerier, beadID string, a config.Agent) beadCheckResul
14701465
}
14711466

14721467
target := a.QualifiedName()
1468+
if strings.TrimSpace(b.Metadata["gc.routed_to"]) == target {
1469+
// Only idempotent if the bead is unassigned or already assigned
1470+
// consistently with the target. Otherwise the bead would be
1471+
// invisible to the target's work_query (which requires --unassigned
1472+
// for pool work in tier 3).
1473+
if b.Assignee == "" || b.Assignee == target {
1474+
return beadCheckResult{Idempotent: true}
1475+
}
1476+
return beadCheckResult{
1477+
Warnings: []string{fmt.Sprintf("warning: bead %s routed to %q but assigned to %q", beadID, target, b.Assignee)},
1478+
}
1479+
}
14731480

1474-
// Fixed agent: check assignee match.
1481+
// Fixed agent: check legacy assignee routing as a compatibility fallback.
14751482
if !isMultiSessionCfgAgent(&a) {
14761483
if b.Assignee == target {
14771484
return beadCheckResult{Idempotent: true}
@@ -1480,6 +1487,9 @@ func checkBeadState(q BeadQuerier, beadID string, a config.Agent) beadCheckResul
14801487
if b.Assignee != "" {
14811488
warnings = append(warnings, fmt.Sprintf("warning: bead %s already assigned to %q", beadID, b.Assignee))
14821489
}
1490+
if routedTo := strings.TrimSpace(b.Metadata["gc.routed_to"]); routedTo != "" {
1491+
warnings = append(warnings, fmt.Sprintf("warning: bead %s already routed to %q", beadID, routedTo))
1492+
}
14831493
for _, l := range b.Labels {
14841494
if strings.HasPrefix(l, "pool:") {
14851495
warnings = append(warnings, fmt.Sprintf("warning: bead %s already has pool label %q", beadID, l))
@@ -1488,17 +1498,24 @@ func checkBeadState(q BeadQuerier, beadID string, a config.Agent) beadCheckResul
14881498
return beadCheckResult{Warnings: warnings}
14891499
}
14901500

1491-
// Pool: check for matching pool label.
1492-
poolLabel := "pool:" + target
1493-
for _, l := range b.Labels {
1494-
if l == poolLabel {
1495-
return beadCheckResult{Idempotent: true}
1501+
// Multi-session targets: pool labels are a legacy fallback only when
1502+
// gc.routed_to is absent. If gc.routed_to is set (even to a different
1503+
// target), it is authoritative — a stale pool label must not short-circuit.
1504+
if strings.TrimSpace(b.Metadata["gc.routed_to"]) == "" {
1505+
poolLabel := "pool:" + target
1506+
for _, l := range b.Labels {
1507+
if l == poolLabel {
1508+
return beadCheckResult{Idempotent: true}
1509+
}
14961510
}
14971511
}
14981512
var warnings []string
14991513
if b.Assignee != "" {
15001514
warnings = append(warnings, fmt.Sprintf("warning: bead %s already assigned to %q", beadID, b.Assignee))
15011515
}
1516+
if routedTo := strings.TrimSpace(b.Metadata["gc.routed_to"]); routedTo != "" {
1517+
warnings = append(warnings, fmt.Sprintf("warning: bead %s already routed to %q", beadID, routedTo))
1518+
}
15021519
for _, l := range b.Labels {
15031520
if strings.HasPrefix(l, "pool:") {
15041521
warnings = append(warnings, fmt.Sprintf("warning: bead %s already has pool label %q", beadID, l))

cmd/gc/cmd_sling_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,25 +2830,25 @@ func TestDryRunNilQuerier(t *testing.T) {
28302830
// --- Idempotency detection (checkBeadState + integration) tests ---
28312831

28322832
func TestCheckBeadStateIdempotentFixedAgent(t *testing.T) {
2833-
q := &fakeQuerier{bead: beads.Bead{ID: "BL-42", Assignee: "mayor"}}
2833+
q := &fakeQuerier{bead: beads.Bead{ID: "BL-42", Metadata: map[string]string{"gc.routed_to": "mayor"}}}
28342834
a := config.Agent{Name: "mayor", MaxActiveSessions: intPtr(1)}
28352835

28362836
result := checkBeadState(q, "BL-42", a)
28372837
if !result.Idempotent {
2838-
t.Error("expected Idempotent=true for matching assignee")
2838+
t.Error("expected Idempotent=true for matching gc.routed_to")
28392839
}
28402840
if len(result.Warnings) != 0 {
28412841
t.Errorf("expected no warnings, got %v", result.Warnings)
28422842
}
28432843
}
28442844

28452845
func TestCheckBeadStateIdempotentPool(t *testing.T) {
2846-
q := &fakeQuerier{bead: beads.Bead{ID: "BL-42", Labels: []string{"pool:hw/polecat"}}}
2846+
q := &fakeQuerier{bead: beads.Bead{ID: "BL-42", Metadata: map[string]string{"gc.routed_to": "hw/polecat"}}}
28472847
a := config.Agent{Name: "polecat", Dir: "hw", MinActiveSessions: intPtr(1), MaxActiveSessions: intPtr(3)}
28482848

28492849
result := checkBeadState(q, "BL-42", a)
28502850
if !result.Idempotent {
2851-
t.Error("expected Idempotent=true for matching pool label")
2851+
t.Error("expected Idempotent=true for matching gc.routed_to")
28522852
}
28532853
if len(result.Warnings) != 0 {
28542854
t.Errorf("expected no warnings, got %v", result.Warnings)
@@ -2857,14 +2857,15 @@ func TestCheckBeadStateIdempotentPool(t *testing.T) {
28572857

28582858
func TestCheckBeadStateIdempotentPoolMultiLabels(t *testing.T) {
28592859
q := &fakeQuerier{bead: beads.Bead{
2860-
ID: "BL-42",
2861-
Labels: []string{"priority:high", "pool:hw/polecat", "sprint:3"},
2860+
ID: "BL-42",
2861+
Labels: []string{"priority:high", "sprint:3"},
2862+
Metadata: map[string]string{"gc.routed_to": "hw/polecat"},
28622863
}}
28632864
a := config.Agent{Name: "polecat", Dir: "hw", MinActiveSessions: intPtr(1), MaxActiveSessions: intPtr(3)}
28642865

28652866
result := checkBeadState(q, "BL-42", a)
28662867
if !result.Idempotent {
2867-
t.Error("expected Idempotent=true for matching pool label among others")
2868+
t.Error("expected Idempotent=true for matching gc.routed_to among other labels")
28682869
}
28692870
}
28702871

@@ -2921,7 +2922,7 @@ func TestDoSlingIdempotentSkipsRouting(t *testing.T) {
29212922
sp := runtime.NewFake()
29222923
cfg := &config.City{Workspace: config.Workspace{Name: "test-city"}}
29232924
a := config.Agent{Name: "mayor", MaxActiveSessions: intPtr(1)}
2924-
q := &fakeQuerier{bead: beads.Bead{ID: "BL-42", Assignee: "mayor"}}
2925+
q := &fakeQuerier{bead: beads.Bead{ID: "BL-42", Metadata: map[string]string{"gc.routed_to": "mayor"}}}
29252926

29262927
deps, stdout, _ := testDeps(cfg, sp, runner.run)
29272928
opts := testOpts(a, "BL-42")

cmd/gc/dispatch_runtime.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ func controlDispatcherBinding(store beads.Store, cityName string, cfg *config.Ci
6464

6565
func applyGraphRouteBinding(step *formula.RecipeStep, binding graphRouteBinding) {
6666
step.Metadata["gc.routed_to"] = binding.qualifiedName
67-
if binding.label != "" {
68-
step.Labels = appendUniqueString(step.Labels, binding.label)
67+
if binding.metadataOnly {
6968
step.Assignee = ""
7069
return
7170
}

cmd/gc/order_dispatch.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,7 @@ func (m *memoryOrderDispatcher) dispatchWisp(ctx context.Context, a orders.Order
256256
}
257257

258258
// Decorate graph workflow recipes with routing metadata so child step
259-
// beads get gc.routed_to set. Without this, only the root bead gets the
260-
// pool label and agents cannot discover their step work.
259+
// beads get gc.routed_to set before instantiation.
261260
if a.Pool != "" {
262261
pool := qualifyPool(a.Pool, a.Rig)
263262
if err := applyGraphRouting(recipe, nil, pool, nil, "", "", "", "", m.store, m.cityName, m.cfg); err != nil {
@@ -287,7 +286,7 @@ func (m *memoryOrderDispatcher) dispatchWisp(ctx context.Context, a orders.Order
287286
}
288287
if a.Pool != "" {
289288
pool := qualifyPool(a.Pool, a.Rig)
290-
args = append(args, fmt.Sprintf("--add-label=pool:%s", pool))
289+
args = append(args, "--set-metadata", "gc.routed_to="+pool)
291290
}
292291
if _, err := m.runner(cityPath, "bd", args...); err != nil {
293292
// Label failure is critical for duplicate-dispatch prevention.

0 commit comments

Comments
 (0)