Skip to content

[duplicate-code] Duplicate Code Pattern: AgentLabels bulk label operations missing shared helper #2558

Description

@github-actions

Part of duplicate code analysis: #2557

Summary

internal/difc/agent.go already has a modifyTag helper (lines 52–59) that abstracts the lock–operate–log pattern for single-tag operations. However, the three bulk tag-operation methods (AddSecrecyTags, AddIntegrityTags, DropIntegrityTags) each duplicate the same ~10-line pattern instead of using an equivalent modifyTags helper.

Duplication Details

Pattern: Bulk label-mutation boilerplate not using helper

  • Severity: Medium

  • Occurrences: 3 functions with identical structure

  • Locations:

    • internal/difc/agent.go lines ~82–91 (DropIntegrityTags)
    • internal/difc/agent.go lines ~93–103 (AddSecrecyTags)
    • internal/difc/agent.go lines ~104–115 (AddIntegrityTags)
  • Existing helper (single-tag — used correctly):

    func (a *AgentLabels) modifyTag(labelType, action, pastTense string, tag Tag, fn func()) {
        logAgent.Printf("Agent %s %s %s tag: %s", a.AgentID, action, labelType, tag)
        a.mu.Lock()
        defer a.mu.Unlock()
        fn()
        log.Printf("[DIFC] Agent %s %s %s tag: %s", a.AgentID, pastTense, labelType, tag)
    }
  • Duplicated bulk pattern (repeated 3 times):

    func (a *AgentLabels) AddSecrecyTags(tags []Tag) {
        logAgent.Printf("Agent %s adding %d secrecy tags", a.AgentID, len(tags))
        a.mu.Lock()
        defer a.mu.Unlock()
        a.Secrecy.Label.AddAll(tags)
        if len(tags) > 0 {
            log.Printf("[DIFC] Agent %s gained secrecy tags: %v", a.AgentID, tags)
        }
    }
    // AddIntegrityTags and DropIntegrityTags are structurally identical

Impact Analysis

  • Maintainability: Any change to the locking strategy, log format, or log level requires touching all three functions independently
  • Bug Risk: Medium — a fix or enhancement applied to one bulk function (e.g., adding a log.Printf prefix change) could easily be missed in the others; the single-tag variant already diverged slightly in format
  • Consistency: The single-tag functions correctly delegate to modifyTag; the bulk functions bypass it, creating an inconsistent API

Refactoring Recommendations

  1. Add a modifyTags helper analogous to modifyTag:
    // modifyTags is a helper for bulk label mutations (analogous to modifyTag).
    func (a *AgentLabels) modifyTags(labelType, action, pastTense string, tags []Tag, fn func()) {
        logAgent.Printf("Agent %s %s %d %s tags", a.AgentID, action, len(tags), labelType)
        a.mu.Lock()
        defer a.mu.Unlock()
        fn()
        if len(tags) > 0 {
            log.Printf("[DIFC] Agent %s %s %s tags: %v", a.AgentID, pastTense, labelType, tags)
        }
    }
    Then refactor the three bulk functions to delegate:
    func (a *AgentLabels) AddSecrecyTags(tags []Tag) {
        a.modifyTags("secrecy", "adding", "gained", tags, func() { a.Secrecy.Label.AddAll(tags) })
    }
    • Extract to: internal/difc/agent.go
    • Estimated effort: ~30 minutes
    • Benefits: single point for locking strategy, log format, and error handling across all bulk operations

Implementation Checklist

  • Review duplication findings
  • Add modifyTags private helper
  • Refactor AddSecrecyTags, AddIntegrityTags, DropIntegrityTags to use helper
  • Update tests to verify behavior is unchanged
  • Verify no functionality broken

Parent Issue

See parent analysis report: #2557
Related to #2557

Generated by Duplicate Code Detector ·

  • expires on Apr 2, 2026, 3:35 AM UTC

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions