Skip to content

Add harness configuration fingerprints#220

Merged
ccf merged 2 commits intomainfrom
feat/harness-configuration-fingerprints
Apr 24, 2026
Merged

Add harness configuration fingerprints#220
ccf merged 2 commits intomainfrom
feat/harness-configuration-fingerprints

Conversation

@ccf
Copy link
Copy Markdown
Owner

@ccf ccf commented Apr 24, 2026

Summary

  • Adds harness configuration fingerprints to maturity analytics, grouping sessions by agent, permission mode, tool set, context signal presence, and customization state.
  • Exposes fingerprint metrics in the API response: session/engineer count, success rate, 10-step compound reliability, leverage score, tool/customization/context counts, and top signals.
  • Adds a Harness Intelligence UI table for the fingerprint catalog and updates the roadmap item to shipped.

Validation

  • ruff check .
  • ruff format --check .
  • bandit -r src/ -c pyproject.toml
  • PYTHONPATH=/Users/ccf/git/primer/src:/Users/ccf/git/primer pytest --import-mode=importlib -v --tb=short - 962 passed
  • ./node_modules/.bin/eslint src/pages/maturity.tsx src/components/maturity/harness-fingerprint-table.tsx src/components/maturity/__tests__/harness-fingerprint-table.test.tsx src/components/maturity/__tests__/maturity-summary.test.tsx src/types/api.ts
  • ./node_modules/.bin/tsc --noEmit
  • ./node_modules/.bin/vitest run --run src/components/maturity/__tests__/harness-fingerprint-table.test.tsx src/components/maturity/__tests__/maturity-summary.test.tsx
  • Pre-push hooks: backend-tests and frontend-tests passed

Note

Medium Risk
Medium risk because it changes maturity analytics computation and API payload shape, which could affect dashboard correctness/performance and downstream consumers expecting the previous schema.

Overview
Adds harness_configuration_fingerprints to the maturity analytics response, computing a SHA-256–based fingerprint that groups sessions by agent_type, permission_mode, tool set, customization state/provenance, and presence/amount of context usage, and returns aggregate metrics (session/engineer counts, success + compound reliability, leverage, and “top” tools/customizations/signals).

Surfaces this new dataset in the frontend via a HarnessFingerprintTable on the Harness Intelligence “Customizations” tab (with empty state + tests), updates API types/schemas, and extends backend/frontend tests to cover the new response field and fingerprint calculations.

Reviewed by Cursor Bugbot for commit 3f679e2. Bugbot is set up for automated code reviews on this repo. Configure here.

@ccf ccf marked this pull request as ready for review April 24, 2026 01:21
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Context signal count is total, not average like peers
    • Changed context_signal_count from a raw sum accumulator to a list-and-average pattern matching tool_count and customization_count, so all three metrics are now per-session averages.

Create PR

Or push these changes by commenting:

@cursor push 40a5268b6e
Preview (40a5268b6e)
diff --git a/src/primer/server/services/maturity_service.py b/src/primer/server/services/maturity_service.py
--- a/src/primer/server/services/maturity_service.py
+++ b/src/primer/server/services/maturity_service.py
@@ -1073,7 +1073,7 @@
                 "leverage_scores": [],
                 "tool_counts": [],
                 "customization_counts": [],
-                "context_signal_count": 0,
+                "context_signal_counts": [],
                 "tools": Counter(),
                 "customizations": Counter(),
                 "signals": Counter(),
@@ -1090,7 +1090,7 @@
                 bucket["success_sessions"].add(row.id)
         bucket["tool_counts"].append(len(tool_names))
         bucket["customization_counts"].append(len(customization_names))
-        bucket["context_signal_count"] += context_count
+        bucket["context_signal_counts"].append(context_count)
         bucket["tools"].update(tool_names)
         bucket["customizations"].update(customization_names)
         bucket["signals"].update(
@@ -1148,7 +1148,11 @@
             )
             if bucket["customization_counts"]
             else 0,
-            context_signal_count=bucket["context_signal_count"],
+            context_signal_count=round(
+                sum(bucket["context_signal_counts"]) / len(bucket["context_signal_counts"])
+            )
+            if bucket["context_signal_counts"]
+            else 0,
             top_tools=[tool for tool, _count in bucket["tools"].most_common(5)],
             top_customizations=[
                 customization for customization, _count in bucket["customizations"].most_common(5)

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 9a9aea3. Configure here.

Comment thread src/primer/server/services/maturity_service.py Outdated
@ccf ccf merged commit 9959a22 into main Apr 24, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant