Skip to content

feat(roadmap-planner): W9 — drop members.pillar_id + cross-pillar % rewrite#196

Merged
danielfbm merged 1 commit into
mainfrom
feat/metrics-w9-drop-pillar-id
May 19, 2026
Merged

feat(roadmap-planner): W9 — drop members.pillar_id + cross-pillar % rewrite#196
danielfbm merged 1 commit into
mainfrom
feat/metrics-w9-drop-pillar-id

Conversation

@danielfbm

Copy link
Copy Markdown
Contributor

Audit follow-up B2 + B5 — 2026-05-19. Depends on W5 (#191) for the jira_key column rename, so this PR is based on the W5 branch. Will be retargeted to main once W5 lands.

Why

members.pillar_id was a single-pillar tag set on the member directory. The audit found it was NULL on all 21 prod rows, which meant the cross-pillar review % metric was structurally pegged at 0% because it compared ma.pillar_id <> mr.pillar_id.

Per maintainer Q9 = option (i): drop the column outright. Cross-pillar % gets redefined to derive both sides from PillarMap instead.

Diff

Layer Change
Schema 0007_drop_members_pillar.sql drops the index first then the column (SQLite needs the explicit order).
Storage Member.PillarID and MemberIdentity.PillarID removed (no alias). UpsertMember / SetMemberIdentity / ListMembers SQL updates in lock-step.
API PATCH /api/contributions/members/:id no longer accepts pillar_id.
Service NetworkDensity cross-pillar % rewritten in Go. PR pillar set = PillarsForRepo(pr.repo_id). Reviewer pillar set = union across PRs the reviewer authored in [from, to) (new pillarsByAuthor helper). A review is cross-pillar when the two sets are disjoint AND both are non-empty. Empty side → excluded from the denominator. Falls back to 0% when no pillars: map is configured.
Cleanup prefills.go stops round-tripping PillarID through MemberIdentity. Storage round-trip test updated to compare display_name instead.

Test plan

  • go test ./... + go vet ./... — green
  • Storage round-trip test (now using display_name for the upsert-vs-update assertion)
  • Dev deploy: confirm migration applies. cross_pillar_review_pct should land at a non-zero value for a window where reviewers cross pillars.

Sequencing

W5 → W9 (this PR). The PR is based on the W5 branch; once W5 merges to main, this PR rebases to main.

Notes

  • members.pillar_id is irrecoverable after the migration. If the operator ever needed a single-pillar member tag again, that'd be a fresh schema design.
  • This PR does not depend on W2 (bot consolidation) but adds an is_bot = 0 filter to the cross-pillar query when both PRs merge (currently the filter is dropped; bot reviewers' empty pillar sets exclude them naturally).

🤖 Generated with Claude Code

@alaudabot alaudabot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review — PR #196

Reviewed 7 files (+144/-37). No critical issues found. Two minor observations and one suggestion:


⚠️ dialect parameter on pillarsByAuthor is unused (service_extras.go:199-202)

The function signature includes dialect storage.Dialect, but the body calls rebindSimple(dialect, ...) where rebindSimple is a local helper that takes dialect as its own parameter — meaning pillarsByAuthor never actually uses the dialect argument for any dialect-specific logic. Consider removing it to reduce noise, or add a comment explaining why it's retained (e.g., if future dialect-specific queries are planned).

func (s *Service) pillarsByAuthor(
	ctx context.Context,
	db *sql.DB,
	q storage.MemberWeekQuery,
	pm *PillarMap,
) (map[string]map[string]struct{}, error) {

⚠️ Variable shadowing observation (service_extras.go:175)

revPillars := revPillarSet[reviewerID] — the name is correct and clear, but it shares a root with the method parameter pm (which is PillarMap). No action required, just noting for readability.


💡 Suggestion: add trailing newline to migration (0007_drop_members_pillar.sql:28)

The file ends without a newline. Adding one improves POSIX compliance and avoids spurious diffs in some editors.


✅ Positive: solid implementation

  • Well-documented migration with clear audit rationale
  • Correct index-drop-before-column-drop order for SQLite compatibility
  • disjointSet efficiently iterates the smaller set first
  • Good defensive PillarMap.Configured() guard
  • Consistent storage layer changes across all three functions
  • Proper defer rows2.Close() for resource cleanup

@alaudabot

alaudabot commented May 19, 2026

Copy link
Copy Markdown
Contributor

🤖 AI Code Review

Property Value
Model opencode/minimax-m2.5-free
Style strict
Issues Found 1
Config Source centralized
Profile ❌ Not Found
Personalized Prompt ❌ No
Prompt Path .github/review/profiles/alaudadevops/toolbox/pr-review.md
Alauda Skills ✅ base-acp-operator-list, base-acp-operator-release, base-authoring, base-m365, base-ocp-operator-list, base-skill-setup, builders-alauda-component-e2e-release, builders-alauda-component-upgrade, builders-alauda-pipeline, builders-claudetask-submit, builders-component-knowledge, builders-confluence, builders-dev-mesh-qa, builders-edge-ci-trace, builders-gitlab-ops, builders-helm-operator-generator, builders-install-cluster-plugin, builders-jira, builders-notify-wecom, builders-olm-operator-lifecycle, builders-prd-to-testcase, builders-publish-errata, builders-roadmap-studio, builders-story-split, builders-violet, builders-webapp-testing, cross-repo-add-mirror, cross-repo-publish, devops-add-bug-release-notes, devops-autodns, devops-bundle-csv-baseline-diff, devops-candidate-version-supervisor, devops-connectors-acceptance-test, devops-connectors-explore, devops-connectors-poc-case, devops-connectors-review, devops-connectors-unit-test, devops-connectors-upgrade-test, devops-connectors-write-user-docs, devops-creating-tekton-pipelines, devops-fix-go-vulns, devops-fork-alauda-binary-release, devops-gen-advanced-form-descriptors, devops-jira-rfd-acceptance, devops-knowledge-adoption, devops-pr-review, devops-refresh-containerfile-digests, devops-refresh-containerfile-tags, devops-replace-strings, devops-scan-docker-keywords, devops-sync-alauda-github-releases, devops-tekton-dynamic-form-optimizer, devops-tekton-operator-task-e2e, devops-tekton-pipeline-delivery, devops-tekton-refresh-results-tag, devops-tekton-task-delivery, devops-tekton-task-overview-template, devops-tekton-task-version-upgrade, devops-tekton-upgrade-notes, devops-tool-report-troubleshoot, devops-ui-e2e-code-audit, devops-ui-e2e-fix-base-on-report, devops-ui-e2e-regression-and-fix, devops-ui-generate-e2e-from-feature, devops-ui-pre-setup, devops-upgrade-go, devops-upstream-backport-cve, devops-upstream-upgrade
Reviewed at 2026-05-19 22:34:35 UTC

Summary

This PR drops the deprecated members.pillar_id column and rewrites the cross-pillar review percentage metric to derive pillars from PillarMap instead. The changes are well-structured with proper migration order (index before column). However, there is an unresolved merge conflict in the config file that must be addressed.

Review Statistics

Category Count
Critical Issues 1
Warnings 0
Suggestions 2
Files Reviewed 8

Critical Issues

  • [config.example.yaml:1-168] (bug/merge-conflict) — Unresolved merge conflict markers (<<<<<<< HEAD, =======, >>>>>>> ee78c5b) remain in the config file. This will cause YAML parsing failures and break the application on startup. The conflict must be resolved by choosing the correct content or merging both sections appropriately.

Warnings

None.

Suggestions

  • [service_extras.go:192] (style/naming) — Consider adding a return type comment or documenting that pillarsByAuthor returns nil on error rather than an empty map, to clarify the distinction between "no authors found" (empty map) and "error occurred" (nil).

  • [service_extras.go:257] (refactor/complexity) — The disjointSet function iterates over the smaller set for O(min(a,b)) complexity. This is good. However, for very large sets, consider noting this in a comment for future optimization with proper set libraries.

Positive Feedback

  • Migration script (0007_drop_members_pillar.sql) correctly drops the index first, then the column — proper SQLite handling.
  • The new cross-pillar algorithm correctly handles edge cases: empty pillar sets on either side are excluded from the denominator, and the algorithm properly uses set disjointness to determine cross-pillar reviews.
  • The disjointSet helper uses an efficient algorithm that iterates over the smaller set.
  • Storage layer changes are thorough — Member, MemberIdentity, UpsertMember, SetMemberIdentity, and ListMembers are all updated consistently.
  • Test updated to use display_name instead of pillar_id for the round-trip assertion — good catch on updating test semantics.
  • The PR description is thorough and explains the audit context and maintainer decision clearly.


ℹ️ About this review

This review was automatically generated using the run-actions workflow.

  • Shared prompt: .github/prompts/code-review.md
  • Config source: centralized
  • Profile path: Not Found
  • Profile ref: e75e733e9aa1b417a8b3c6441e53495dbcb418ad
  • No repository-specific prompt configured
  • Alauda skills: base-acp-operator-list, base-acp-operator-release, base-authoring, base-m365, base-ocp-operator-list, base-skill-setup, builders-alauda-component-e2e-release, builders-alauda-component-upgrade, builders-alauda-pipeline, builders-claudetask-submit, builders-component-knowledge, builders-confluence, builders-dev-mesh-qa, builders-edge-ci-trace, builders-gitlab-ops, builders-helm-operator-generator, builders-install-cluster-plugin, builders-jira, builders-notify-wecom, builders-olm-operator-lifecycle, builders-prd-to-testcase, builders-publish-errata, builders-roadmap-studio, builders-story-split, builders-violet, builders-webapp-testing, cross-repo-add-mirror, cross-repo-publish, devops-add-bug-release-notes, devops-autodns, devops-bundle-csv-baseline-diff, devops-candidate-version-supervisor, devops-connectors-acceptance-test, devops-connectors-explore, devops-connectors-poc-case, devops-connectors-review, devops-connectors-unit-test, devops-connectors-upgrade-test, devops-connectors-write-user-docs, devops-creating-tekton-pipelines, devops-fix-go-vulns, devops-fork-alauda-binary-release, devops-gen-advanced-form-descriptors, devops-jira-rfd-acceptance, devops-knowledge-adoption, devops-pr-review, devops-refresh-containerfile-digests, devops-refresh-containerfile-tags, devops-replace-strings, devops-scan-docker-keywords, devops-sync-alauda-github-releases, devops-tekton-dynamic-form-optimizer, devops-tekton-operator-task-e2e, devops-tekton-pipeline-delivery, devops-tekton-refresh-results-tag, devops-tekton-task-delivery, devops-tekton-task-overview-template, devops-tekton-task-version-upgrade, devops-tekton-upgrade-notes, devops-tool-report-troubleshoot, devops-ui-e2e-code-audit, devops-ui-e2e-fix-base-on-report, devops-ui-e2e-regression-and-fix, devops-ui-generate-e2e-from-feature, devops-ui-pre-setup, devops-upgrade-go, devops-upstream-backport-cve, devops-upstream-upgrade

@danielfbm danielfbm force-pushed the feat/metrics-w5-jira-key-rename branch from 3c96cf0 to 520cc4a Compare May 19, 2026 22:17
Base automatically changed from feat/metrics-w5-jira-key-rename to main May 19, 2026 22:17
@alaudabot

Copy link
Copy Markdown
Contributor

Summary

This PR implements W9 of the audit follow-up: dropping the unused members.pillar_id column and rewriting the cross-pillar review % calculation to derive pillar attribution from the configured PillarMap instead. Also includes W5 changes (rename epic_key to jira_key). The implementation is sound with proper migration ordering and the new cross-pillar logic correctly derives both PR and reviewer pillar sets from repo mappings.

Review Statistics

Category Count
Critical Issues 0
Warnings 0
Suggestions 0
Files Reviewed 11

Critical Issues

Issues that MUST be addressed before merging (security, bugs, breaking changes)

None identified.

Warnings

Issues that SHOULD be addressed but are not blocking

None identified.

Suggestions

Recommendations for improvement (nice to have)

None identified.

Positive Feedback

  • Well-documented migrations: Both 0006_rename_epic_key_to_jira_key.sql and 0007_drop_members_pillar.sql include detailed comments explaining the rationale, audit data, and compatibility notes.
  • Clean cross-pillar rewrite: The new pillarsByAuthor helper correctly derives reviewer pillar sets from their authored PRs in the time window, and the disjointSet helper efficiently checks for no overlap.
  • Proper fallback handling: The code correctly falls back to 0% cross-pillar when PillarMap is not configured (!pm.Configured()) and excludes reviews where either side has empty pillar sets.
  • Consistent renames: The epic_keyjira_key rename is applied consistently across github/gitlab syncers, storage layer, and SQL queries.
  • Test update: The storage round-trip test properly switched to comparing display_name instead of the removed PillarID field.

…ewrite

Audit follow-up B2 + B5 (2026-05-19). Depends on W5 (this PR is based
on feat/metrics-w5-jira-key-rename so the renamed column is
available).

The `members.pillar_id` column was a single-pillar tag set on the
member that the audit found was NULL on all 21 prod rows. The
cross-pillar review % was structurally pegged at 0% because it
compared `ma.pillar_id <> mr.pillar_id`. Per maintainer Q9 =
option (i): drop the column outright and rewrite the metric.

Schema:
- Migration 0007_drop_members_pillar.sql drops the index first then
  the column (SQLite refuses DROP COLUMN with a dependent index).

API:
- storage.Member.PillarID and MemberIdentity.PillarID removed (no
  alias).
- PATCH /api/contributions/members/:id stops accepting `pillar_id`.
- UpsertMember / SetMemberIdentity / ListMembers SQL updates.
- prefills.go drops the round-tripped PillarID write.
- storage round-trip test updates accordingly.

NetworkDensity:
- Cross-pillar review % rewritten in Go. Each PR's pillar set comes
  from PillarMap.PillarsForRepo(pr.repo_id). Each reviewer's pillar
  set is the union of pillars across PRs they authored in the same
  window (pillarsByAuthor helper). A review is cross-pillar when
  the two sets are disjoint AND both are non-empty. Empty either
  side → excluded from the denominator (we cannot answer the
  question).
- Falls back to 0% when no pillar map is configured.

Rollback: empty pillar map in config or drop the migration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@danielfbm danielfbm force-pushed the feat/metrics-w9-drop-pillar-id branch from f275235 to 6147316 Compare May 19, 2026 22:33
@danielfbm danielfbm merged commit b41f85f into main May 19, 2026
6 of 8 checks passed
@danielfbm danielfbm deleted the feat/metrics-w9-drop-pillar-id branch May 19, 2026 22:33
@alaudabot

Copy link
Copy Markdown
Contributor

Review Summary

Critical Issue Found: The file contains unresolved merge conflict markers (, , ). This will cause YAML parsing failures and break the application on startup.

Issues Count: 1 Critical

Please resolve this conflict before the next deployment.

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.

2 participants