[hermes] metis: go:S3776 #157

Open
opened 2026-09-24 14:28:35 +00:00 by hermes-automation · 0 comments

SonarQube reports go:S3776 in pkg/sentinel/collector.go. The build is green; this is a standing finding, not a failure.

What is wrong

collectUSBScratch mixes mount-health checks, device resolution/blkid health checks, and bind-target evaluation (with nested ifs, &&, and an else) all in one function body, pushing cognitive complexity to 17. Extracting the device-resolution/health logic and the bind-target loop into small helper functions removes nesting levels and the else branch without changing any outcome.

Ariadne opened no pull request for it: no automated patch was possible for this finding.

Facts

  • gitea — Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed. (CRITICAL, 7min estimated) (pkg/sentinel/collector.go:131)

Suggested fix (not applied)

Hermes could not open a pull request for this, so the change below was not written, validated, or pushed anywhere. It is a starting point for whoever picks this up, not a reviewed patch.

pkg/sentinel/collector.go — Split collectUSBScratch into itself plus three small helpers (resolveDevice, applyDeviceHealth, collectBindTargets). Each helper keeps the exact same conditions and order of operations, but moving them out lowers nesting depth and removes the else branch (replaced by an early return), bringing the parent function's cognitive complexity under 15 while every field is still set the same way.

func collectUSBScratch() *facts.USBScratch {
	cfg, ok := loadNodeConfig()
	if !ok || cfg.USBScratch == nil {
		return nil
	}
	desired := cfg.USBScratch
	scratch := &facts.USBScratch{
		Mountpoint: desired.Mountpoint,
		UUID:       desired.UUID,
		Label:      desired.Label,
		FS:         desired.FS,
	}

	source, fsType, mounted := mountInfo(desired.Mountpoint)
	scratch.MountHealthy = mounted && strings.TrimSpace(source) != ""
	if scratch.MountHealthy && desired.FS != "" && fsType != "" {
		scratch.MountHealthy = strings.EqualFold(fsType, desired.FS)
	}
	if scratch.FS == "" && fsType != "" {
		scratch.FS = fsType
	}

	device := resolveDevice(source, desired)
	applyDeviceHealth(scratch, desired, device)

	scratch.BindTargets, scratch.BindHealthy = collectBindTargets(desired.BindTargets, desired.Mountpoint)
	return scratch
}

func resolveDevice(source string, desired *usbScratchConfig) string {
	device := source
	if device == "" && desired.UUID != "" {
		device = resolveDeviceByUUID(desired.UUID)
	}
	if device == "" && desired.Label != "" {
		device = resolveDeviceByLabel(desired.Label)
	}
	return device
}

func applyDeviceHealth(scratch *facts.USBScratch, desired *usbScratchConfig, device string) {
	if device == "" {
		return
	}
	export := blkidExport(device)
	if desired.UUID != "" {
		scratch.UUIDHealthy = export["UUID"] == desired.UUID
	}
	if desired.Label != "" {
		scratch.LabelHealthy = export["LABEL"] == desired.Label
	}
	if scratch.FS == "" {
		scratch.FS = export["TYPE"]
	}
}

func collectBindTargets(targets []string, mountpoint string) ([]facts.USBBindTarget, bool) {
... (truncated)

Filed automatically by Ariadne from a Hermes Agent diagnosis (run run_04939157451949df92692517fa2bc1eb). Hermes has no write access to this repository; no files or infrastructure were changed.

SonarQube reports **go:S3776** in `pkg/sentinel/collector.go`. The build is green; this is a standing finding, not a failure. ## What is wrong collectUSBScratch mixes mount-health checks, device resolution/blkid health checks, and bind-target evaluation (with nested ifs, &&, and an else) all in one function body, pushing cognitive complexity to 17. Extracting the device-resolution/health logic and the bind-target loop into small helper functions removes nesting levels and the else branch without changing any outcome. Ariadne opened no pull request for it: no automated patch was possible for this finding. ## Facts - **gitea** — Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed. (CRITICAL, 7min estimated) (`pkg/sentinel/collector.go:131`) ## Suggested fix (not applied) Hermes could not open a pull request for this, so the change below was not written, validated, or pushed anywhere. It is a starting point for whoever picks this up, not a reviewed patch. **`pkg/sentinel/collector.go`** — Split collectUSBScratch into itself plus three small helpers (resolveDevice, applyDeviceHealth, collectBindTargets). Each helper keeps the exact same conditions and order of operations, but moving them out lowers nesting depth and removes the else branch (replaced by an early return), bringing the parent function's cognitive complexity under 15 while every field is still set the same way. ``` func collectUSBScratch() *facts.USBScratch { cfg, ok := loadNodeConfig() if !ok || cfg.USBScratch == nil { return nil } desired := cfg.USBScratch scratch := &facts.USBScratch{ Mountpoint: desired.Mountpoint, UUID: desired.UUID, Label: desired.Label, FS: desired.FS, } source, fsType, mounted := mountInfo(desired.Mountpoint) scratch.MountHealthy = mounted && strings.TrimSpace(source) != "" if scratch.MountHealthy && desired.FS != "" && fsType != "" { scratch.MountHealthy = strings.EqualFold(fsType, desired.FS) } if scratch.FS == "" && fsType != "" { scratch.FS = fsType } device := resolveDevice(source, desired) applyDeviceHealth(scratch, desired, device) scratch.BindTargets, scratch.BindHealthy = collectBindTargets(desired.BindTargets, desired.Mountpoint) return scratch } func resolveDevice(source string, desired *usbScratchConfig) string { device := source if device == "" && desired.UUID != "" { device = resolveDeviceByUUID(desired.UUID) } if device == "" && desired.Label != "" { device = resolveDeviceByLabel(desired.Label) } return device } func applyDeviceHealth(scratch *facts.USBScratch, desired *usbScratchConfig, device string) { if device == "" { return } export := blkidExport(device) if desired.UUID != "" { scratch.UUIDHealthy = export["UUID"] == desired.UUID } if desired.Label != "" { scratch.LabelHealthy = export["LABEL"] == desired.Label } if scratch.FS == "" { scratch.FS = export["TYPE"] } } func collectBindTargets(targets []string, mountpoint string) ([]facts.USBBindTarget, bool) { ... (truncated) ``` ## Links - SonarQube finding: https://quality.bstein.dev/project/issues?resolved=false&id=metis&open=AZ2z_XbbKy9i4pkIqvM9 - Full evidence bundle and audit trail live in Ariadne at `/api/admin/audit/events`, event types `hermes_autotriage_incident` and `hermes_autotriage_diagnosis`. Filed automatically by Ariadne from a Hermes Agent diagnosis (run [run_04939157451949df92692517fa2bc1eb](https://triage.bstein.dev/chat?resume=run_04939157451949df92692517fa2bc1eb)). Hermes has no write access to this repository; no files or infrastructure were changed. <!-- hermes-triage job=metis classification=go:S3776 incident=sonar/metis/go:S3776/AZ2z_XbbKy9i4pkIqvM9 -->
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: titan/metis#157
No description provided.