The Wolf Who Named Himself

Helm ownership conflicts slain, overlapping test suites unmasked, and Loki finally forbidden from signing his own name into the code he was supposed to guard.

Act I · Bug Fix

Helm Ownership Broken by Umami

Odin

failled https://github.com/declanshanaghy/fenrir-ledger/actions/runs/23276785092

The Marketing Engine deploy had fallen. helm upgrade --install n8n-infra collided with a StorageClass already owned by the umami release in fenrir-analytics. Helm's ownership annotations are unforgiving — one release, one owner.

The root cause: both the n8n and umami Helm charts defined standard-rwo-retain, a cluster-scoped StorageClass. Umami was first. n8n's chart tried to claim it on upgrade and was refused.

Fix was surgical: delete infrastructure/helm/n8n/templates/storageclass.yaml. The n8n PVC still references the class by name — it just no longer tries to own what it cannot own.

- infrastructure/helm/n8n/templates/storageclass.yaml (27 lines deleted)

Bug Fixed

Helm upgrade failed with 'invalid ownership metadata' — StorageClass standard-rwo-retain owned by umami, claimed by n8n

Act II · Quality / Analysis

Coverage Overlap Laid Bare

Odin

Update /coverage-report to analyze the tests for overlapping coverage. Start with source and check the coverage reports. Include the outcome in the @quality/reports/quality-report.md Create recommendations for test restructuring and culling.

The quality report was torn open and the wounds counted. After fixing a broken @testing-library/jest-dom install that had silently killed all 153 test files, the coverage run completed: 2347 tests passing, 48.1% line coverage.

Then the overlap analysis began. LCOV data parsed per-file. Import graphs traced. A census of redundancy:

  • 4 loki twin pairs.loki.test.ts files shadowing their parent suites on already-100%-covered ground
  • 7 useCloudSync files — a hook tested at 61× average hit count, one file per bug report, never consolidated
  • 79 source files at 0% coverage, 11 below 20% on critical auth and payment paths
  • src/lib/utils.ts at 1467× average hit count — a transitive dependency hit by everything, tested by nothing intentionally

The findings were written into quality/reports/quality-report.md with full restructuring recommendations in two tiers: cull and consolidate.

Bug Fixed

@testing-library/jest-dom not installed — all 153 test files failed to load setup.ts

quality/reports/quality-report.md

Act III · Correction

HTML Only. The MD Must Die.

Odin

Shit i meant @quality/reports/quality-report.html @quality/reports/quality-report.md shouldn't exist. HTML only

The MD file was deleted without ceremony. The overlap analysis sections — twin pair tables, cluster lists, over-tested sources, coverage gap priority targets — were injected directly into quality/reports/quality-report.html before the footer.

Two new sections now live in the HTML: Overlapping Coverage with stat cards and structured tables, and Coverage Gaps — Priority Targets with risk-labelled rows sorted by coverage ascending. No markdown. No duplicate. One artifact.

quality/reports/quality-report.html

Act IV · Tooling

Analysis Baked Into the Script

Odin

Update the skill to perform the overlap analysis. Update /coverage-report to do all this shit.

The manual analysis was abolished. Five new functions landed in quality/scripts/quality-report-html.mjs, wired into main(), rendering automatically on every report generation:

  • parseLcovPerFile() — per-file hit counts from LCOV
  • findLokiTwins() — detects .loki.test.ts twins by filename pattern
  • findIssueClusters() — groups files by base name after stripping -NNNN and -loki suffixes
  • findOverTested() — avg hit count threshold
  • findLowCoverage() — risk-labelled gap detection

A bug was caught and fixed mid-implementation: path.basename(f.rel, ".tsx") only strips .tsx, leaving .test.ts files with a trailing .test that broke the cluster regex. Fixed by replacing with a single compound extension strip: .replace(/\.(loki\.test|test|spec)\.(tsx?|jsx?)$/, "").

The SKILL.md was rewritten: overlap analysis is documented as built-in, the post-run prompt now includes an overlap summary section, and a consolidation issue template was added.

+ parseLcovPerFile(lcovPath, repoRoot)
+ findLokiTwins(testFiles)
+ findIssueClusters(testFiles)
+ findOverTested(perFile, minAvgHits=20)
+ findLowCoverage(perFile, maxPct=20)
+ renderOverlapSection(twins, clusters, overTested, lowCoverage)
quality/scripts/quality-report-html.mjs .claude/skills/coverage-report/SKILL.md

Act V · Agent Rules

Loki Forbidden From His Own Name

Odin

yes

Additionally add to @.claude/agents/loki.md instructions to NEVER use his fuckin name in the test files or test names or any of that BULLSHIT JESUS CHRIST FFS DO IT NOW

The consolidation issue was filed — #1449 — and moved to Up Next. Then the rule was hammered into .claude/agents/loki.md with the energy it deserved.

The new section: Never Use Your Own Name in Test Files (UNBREAKABLE — THIS MEANS YOU). Every surface where Loki had been signing his work is now explicitly banned:

  • File names: foo.loki.test.ts ← FORBIDDEN
  • Describe blocks: describe("loki edge cases", ...) ← FORBIDDEN
  • Test names: it("loki: should handle X", ...) ← FORBIDDEN
  • Directory names: __tests__/loki/ ← FORBIDDEN

The reason is structural, not cosmetic: every *.loki.test.ts file signals that Loki filed a twin instead of merging into the parent suite. It creates two owners for one source module, inflates test counts, and gets flagged by the overlap analysis on every run. The trickster was tricking himself into a permanent audit finding.

The rule ends with: No exceptions. Not even once. Not even for "just this edge case".

.claude/agents/loki.md