Skip to content

complexity router: remove config.json as authoritative as default and merge the keywords + move to hash based reconcilation#4293

Closed
Madhuvod wants to merge 1 commit into
devfrom
06-11-complexity_router_remove_config.json_as_authoritative_always_and_merge_the_keywords_move_to_hash_based_reconcilation
Closed

complexity router: remove config.json as authoritative as default and merge the keywords + move to hash based reconcilation#4293
Madhuvod wants to merge 1 commit into
devfrom
06-11-complexity_router_remove_config.json_as_authoritative_always_and_merge_the_keywords_move_to_hash_based_reconcilation

Conversation

@Madhuvod

@Madhuvod Madhuvod commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Briefly explain the purpose of this PR and the problem it solves.

Changes

  • What was changed and why
  • Any notable design decisions or trade-offs

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

Describe the steps to validate this change. Include commands and expected outcomes.

# Core/Transports
go version
go test ./...

# UI
cd ui
pnpm i || npm i
pnpm test || npm test
pnpm build || npm run build

If adding new configs or environment variables, document them here.

Screenshots/Recordings

If UI changes, add before/after screenshots or short clips.

Breaking changes

  • Yes
  • No

If yes, describe impact and migration instructions.

Related issues

Link related issues and discussions. Example: Closes #123

Security considerations

Note any security implications (auth, secrets, PII, sandboxing, etc.).

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

Summary by CodeRabbit

  • Documentation

    • Clarified governance complexity analyzer and Helm guidance for source_of_truth modes (split vs config.json), and when runtime/UI/API edits persist vs file config is authoritative.
  • New Features

    • File-based complexity analyzer updates now merge with stored runtime values as appropriate and track a canonical file hash to guide reconciliation.
  • Tests

    • Added tests for merging, hashing, and persistence behaviors.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a non-JSON ConfigHash to ComplexityAnalyzerConfig, deterministic hash generation and merge utilities, persists and reads the hash in the config store, implements reconciliation helpers for split vs config.json source_of_truth modes, and updates transport logic, tests, and docs.

Changes

Complexity Analyzer Config Hash & Split-Mode Reconciliation

Layer / File(s) Summary
Docs: Helm & feature notes
docs/deployment-guides/helm/governance.mdx, docs/features/governance/complexity-router.mdx
Clarify Helm behavior and source_of_truth semantics: in split Helm-updated tier boundaries/keywords append/merge while UI/API edits persist across restarts if file unchanged; set bifrost.sourceOfTruth: "config.json" to make file authoritative.
ComplexityAnalyzerConfig struct and normalization
framework/configstore/complexityconfig.go
Add ConfigHash string \json:"-"`and ensureNormalized()preservesConfigHash; import crypto/sha256andencoding/hex`.
Hash generation and merge functions
framework/configstore/complexityconfig.go
GenerateComplexityAnalyzerConfigHash produces a deterministic SHA-256 hex digest of a normalized config (clearing ConfigHash before marshal). MergeComplexityAnalyzerConfig overlays tier boundaries and union-merges keyword lists; internal helper concatenates and normalizes keywords.
Config keys: add stored-hash key
framework/configstore/tables/config.go
Add exported ConfigComplexityAnalyzerConfigHashKey constant to store last synced analyzer config JSON hash.
Config store read/write changes
framework/configstore/rdb.go
GetGovernanceConfig/GetComplexityAnalyzerConfig read stored hash and attach to decoded ComplexityAnalyzerConfig. UpdateComplexityAnalyzerConfig conditionally persists the hash (transaction-wrapped when necessary) and skips hash write when empty.
RDB tests for hash & merge behavior
framework/configstore/rdb_test.go
Extend tests: persist/assert stored ConfigHash, ensure runtime updates with empty incoming hash preserve stored hash while updating boundaries, validate canonical hash invariance, and verify deterministic merge results.
Transport reconciliation helpers
transports/bifrost-http/lib/config.go
Replace inline logic with reconcileComplexityAnalyzerConfig, complexityAnalyzerConfigFromFile, mergeComplexityAnalyzerConfigFromFile, and syncComplexityAnalyzerConfig to compute file hash, hash-gate split-mode merge vs config.json authoritative sync, and equality-gated persistence into in-memory governance config.
Transport tests & mock adjustments
transports/bifrost-http/lib/config_test.go
Mock UpdateComplexityAnalyzerConfig backfills empty incoming ConfigHash from stored config; expand tests to cover hash-match preservation, keyword-list union when file hash changes, and config.json authoritative replacement; add helpers/fixtures.

Sequence Diagram(s)

sequenceDiagram
  participant File as config.json (file)
  participant Loader as loadGovernanceConfig
  participant Reconciler as reconcileComplexityAnalyzerConfig
  participant Runtime as in-memory GovernanceConfig
  participant Store as ConfigStore (governance_config)

  File->>Loader: provide Governance ComplexityAnalyzerConfig
  Loader->>Reconciler: complexityAnalyzerConfigFromFile(file)
  Reconciler->>Store: GetComplexityAnalyzerConfig() (reads typed config + stored hash)
  Reconciler->>Reconciler: compare fileHash vs stored.ConfigHash
  alt source_of_truth == "config.json" or hash differs
    Reconciler->>Runtime: merge or replace config (file authoritative)
    Reconciler->>Store: UpdateComplexityAnalyzerConfig(merged, write hash)
  else hash matches (split mode)
    Reconciler->>Runtime: preserve stored/runtime config
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • maximhq/bifrost#3968: Overlapping changes to transports/bifrost-http/lib/config.go source_of_truth reconciliation that relate to file-authoritative behavior.
  • maximhq/bifrost#3712: Prior work on ComplexityAnalyzerConfig persistence and config-store plumbing that this PR extends with hashing and merge logic.
  • maximhq/bifrost#3948: Helm templates rendering bifrost.governance.complexityAnalyzerConfig into config.json, related to the docs and reconciliation behavior here.

Suggested reviewers

  • akshaydeo
  • danpiths
  • roroghost17

Poem

🐰 I hop through hashes, keys, and merge,

I stitch file rules with runtime's surge;
Split keeps edits, config.json leads,
Keywords join like shared carrots and seeds;
Tests nod approval — now deploy with a verge.

🚥 Pre-merge checks | ✅ 1 | ❌ 4

❌ Failed checks (3 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is entirely a template with no actual content filled in; all sections are empty placeholders without any explanation of the changes, design decisions, affected areas, testing details, or related issues. Complete the PR description by filling in meaningful content for Summary, Changes, affected areas (Core, Transports), testing instructions, and link to related issues. Include any breaking changes and security considerations.
Linked Issues check ⚠️ Warning The linked issue (#123) is about Files API support for providers, which is unrelated to the PR's focus on complexity router configuration, keyword merging, and hash-based reconciliation. Link the correct issue(s) related to complexity router changes. Unlink #123 as it addresses a different feature (Files API) not implemented in this PR.
Docstring Coverage ⚠️ Warning Docstring coverage is 39.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive The PR title and code changes indicate focus on complexity router configuration handling, but the linked issue references Files API support, making it unclear whether all changes align with stated objectives. Link the correct issue(s) for complexity router changes and verify all code modifications support those objectives, or confirm if Files API changes are also included.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: removing config.json as default authority, implementing keyword merging, and adopting hash-based reconciliation for complexity router configuration.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 06-11-complexity_router_remove_config.json_as_authoritative_always_and_merge_the_keywords_move_to_hash_based_reconcilation

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Comment @coderabbitai help to get the list of available commands and usage tips.

Madhuvod commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

@Madhuvod Madhuvod marked this pull request as ready for review June 11, 2026 13:22

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/features/governance/complexity-router.mdx`:
- Around line 184-186: Add documentation for the governance.source_of_truth
config: update the config.json example to include the governance.source_of_truth
field (showing valid values "split" and "config.json" and the default "split")
and update the field table to document source_of_truth as a string, optional,
default "split", with a brief description ("Reconciliation mode: 'split'
(default) merges file changes with runtime edits; 'config.json' makes the file
authoritative on every restart"). Reference the governance.source_of_truth key
in the example and the table so users editing config.json directly can see the
JSON path, allowed values, and default.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b1dea81a-03fa-4ac4-9def-0e504a54bef9

📥 Commits

Reviewing files that changed from the base of the PR and between 575ff8d and 8502674.

📒 Files selected for processing (8)
  • docs/deployment-guides/helm/governance.mdx
  • docs/features/governance/complexity-router.mdx
  • framework/configstore/complexityconfig.go
  • framework/configstore/rdb.go
  • framework/configstore/rdb_test.go
  • framework/configstore/tables/config.go
  • transports/bifrost-http/lib/config.go
  • transports/bifrost-http/lib/config_test.go

Comment thread docs/features/governance/complexity-router.mdx
@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

Safe to merge — the core concurrency fix and transactional two-row write are both implemented correctly, and the new reconciliation logic is well-covered by tests.

The two previously-flagged issues are both properly resolved. The remaining comments are about implicit API contracts and monotonic keyword accumulation semantics, neither of which causes incorrect behavior under current usage.

No files require special attention, though the keyword-growth semantics in transports/bifrost-http/lib/config.go could use a clarifying comment.

Important Files Changed

Filename Overview
framework/configstore/complexityconfig.go Adds ConfigHash field, GenerateComplexityAnalyzerConfigHash, MergeComplexityAnalyzerConfig, and mergeComplexityKeywordLists helpers; hash is excluded from JSON serialization and Normalized() propagates it correctly.
framework/configstore/rdb.go GetComplexityAnalyzerConfig now uses a single IN-query to fetch config and hash atomically (fixing previous two-read window); UpdateComplexityAnalyzerConfig dispatched to extracted helper and wraps both writes in a transaction only when ConfigHash is set.
framework/configstore/rdb_test.go Good new tests covering round-trip with hash, runtime-update hash preservation, and hash canonicalization; merge semantics are also exercised.
framework/configstore/tables/config.go Adds ConfigComplexityAnalyzerConfigHashKey constant for the new hash row stored in the existing governance_config key-value table; no migration required.
transports/bifrost-http/lib/config.go Replaces file-authoritative overwrite with reconcileComplexityAnalyzerConfig; hash-based change detection is clean, but keyword lists grow monotonically in split mode (removing a file keyword after a prior merge leaves it in the DB).
transports/bifrost-http/lib/config_test.go New tests cover hash-match skip, hash-change merge, and config.json source-of-truth mode; MockConfigStore hash-preservation semantics still diverge subtly from the real RDB store.
docs/features/governance/complexity-router.mdx Warning block replaced with a Note describing the split-mode union merge and config.json source-of-truth option; accurately reflects the new behavior.
docs/deployment-guides/helm/governance.mdx Updated Helm note to describe split mode keyword-union semantics and how to switch to config.json authoritativeness; consistent with code behavior.

Reviews (3): Last reviewed commit: "complexity router: remove config.json as..." | Re-trigger Greptile

Comment thread framework/configstore/rdb.go Outdated
Comment thread framework/configstore/rdb.go
@Madhuvod Madhuvod force-pushed the 06-11-complexity_router_remove_config.json_as_authoritative_always_and_merge_the_keywords_move_to_hash_based_reconcilation branch from 8502674 to 8c263b3 Compare June 11, 2026 13:47
@Madhuvod Madhuvod changed the title complexity router: remove config.json as authoritative always and merge the keywords + move to hash based reconcilation complexity router: remove config.json as authoritative as default and merge the keywords + move to hash based reconcilation Jun 11, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/deployment-guides/helm/governance.mdx`:
- Line 409: Update the wording to clarify split-mode merge/persistence: state
that source_of_truth: "split" causes Helm-configured keywords to be merged
(unioned) with stored lists rather than replacing them, and replace ambiguous
phrases like "while the rendered file value is unchanged"/"while the file value
is unchanged" with an explicit statement such as "the config.json file on disk
does not reflect runtime UI/API edits; those edits are preserved in runtime
state but not written back to config.json." Also correct the Helm guide setting
name from bifrost.sourceOfTruth to bifrost.governance.sourceOfTruth to match the
governance.* configuration structure.

In `@framework/configstore/complexityconfig.go`:
- Around line 143-151: The merged ComplexityAnalyzerConfig being constructed in
the merged variable omits the file's ConfigHash so callers (e.g.,
UpdateComplexityAnalyzerConfig) never persist
ConfigComplexityAnalyzerConfigHashKey; fix by carrying the
normalizedFile.ConfigHash into the merged struct (assign ConfigHash from
normalizedFile to the new ComplexityAnalyzerConfig) so the merged result
preserves the file hash used by reconciliation.

In `@transports/bifrost-http/lib/config.go`:
- Line 2366: The initial-creation path fails to set
ComplexityAnalyzerConfig.ConfigHash causing the first persisted governance row
to be hashless; update createGovernanceConfigInStore (the code path exercised by
loadGovernanceConfig) to compute the same normalized+hashed value used by
reconcileComplexityAnalyzerConfig and assign it to
ComplexityAnalyzerConfig.ConfigHash before persisting so startup reconciliation
treats the freshly-created config the same as subsequent reconciled rows.
- Around line 2458-2466: The function syncComplexityAnalyzerConfig currently
assigns config.GovernanceConfig.ComplexityAnalyzerConfig = next before
persisting via config.ConfigStore.UpdateComplexityAnalyzerConfig, risking
in-memory/durable inconsistency on write failure; change the flow in
syncComplexityAnalyzerConfig to first check reflect.DeepEqual(current, next),
then call config.ConfigStore.UpdateComplexityAnalyzerConfig(ctx, next) and only
upon a successful return assign config.GovernanceConfig.ComplexityAnalyzerConfig
= next (and propagate or handle the error instead of only logging) so the
durable store is updated before swapping the live config.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9c5cff17-3730-41a3-af8c-e9aaed27bc2c

📥 Commits

Reviewing files that changed from the base of the PR and between 8502674 and 8c263b3.

📒 Files selected for processing (8)
  • docs/deployment-guides/helm/governance.mdx
  • docs/features/governance/complexity-router.mdx
  • framework/configstore/complexityconfig.go
  • framework/configstore/rdb.go
  • framework/configstore/rdb_test.go
  • framework/configstore/tables/config.go
  • transports/bifrost-http/lib/config.go
  • transports/bifrost-http/lib/config_test.go

Comment thread docs/deployment-guides/helm/governance.mdx Outdated
Comment thread framework/configstore/complexityconfig.go
Comment thread transports/bifrost-http/lib/config.go
Comment thread transports/bifrost-http/lib/config.go
…ge the keywords + move to hash based reconcilation
@Madhuvod Madhuvod force-pushed the 06-11-complexity_router_remove_config.json_as_authoritative_always_and_merge_the_keywords_move_to_hash_based_reconcilation branch from 8c263b3 to 99974c2 Compare June 11, 2026 14:15

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/features/governance/complexity-router.mdx (1)

150-178: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add source_of_truth field documentation to the config.json tab.

The Note at lines 184–186 references source_of_truth: "split" and source_of_truth: "config.json" modes, but the config.json example (lines 150–168) and field table (lines 170–178) don't show this field. Readers editing config.json directly won't know the JSON path, valid values, or default.

Based on the schema and Helm guide, add:

  • In the config.json example (after line 152): "source_of_truth": "split",
  • In the field table (after line 178): a row documenting source_of_truth as string, optional, default "split", with valid values "split" (merge file changes with runtime edits) and "config.json" (file authoritative on restart)

Note: This was acknowledged in a previous review comment thread.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/features/governance/complexity-router.mdx` around lines 150 - 178, The
config.json example is missing the source_of_truth field referenced later; add a
"source_of_truth": "split" entry to the JSON example (adjacent to the existing
governance.complexity_analyzer_config block) and update the field table to
include a row for source_of_truth (type: string, required: No, default: "split",
valid values: "split" — merge file changes with runtime edits; "config.json" —
file authoritative on restart) so readers editing config.json know the path,
valid values, and default.
♻️ Duplicate comments (1)
docs/deployment-guides/helm/governance.mdx (1)

409-409: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Correct the Helm values path to match the governance namespace.

The instruction to set bifrost.sourceOfTruth: "config.json" should be bifrost.governance.sourceOfTruth: "config.json" to match the governance.* structure used throughout this guide (lines 432–465 show all other governance settings nested under bifrost.governance).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/deployment-guides/helm/governance.mdx` at line 409, Update the Helm
values key to the governance-namespaced setting: replace any use of
bifrost.sourceOfTruth with bifrost.governance.sourceOfTruth in the documentation
text so it matches the governance.* structure used elsewhere; ensure the example
and explanatory sentence use bifrost.governance.sourceOfTruth: "config.json" and
adjust any neighboring references in the same paragraph to maintain consistency
with other governance settings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@docs/features/governance/complexity-router.mdx`:
- Around line 150-178: The config.json example is missing the source_of_truth
field referenced later; add a "source_of_truth": "split" entry to the JSON
example (adjacent to the existing governance.complexity_analyzer_config block)
and update the field table to include a row for source_of_truth (type: string,
required: No, default: "split", valid values: "split" — merge file changes with
runtime edits; "config.json" — file authoritative on restart) so readers editing
config.json know the path, valid values, and default.

---

Duplicate comments:
In `@docs/deployment-guides/helm/governance.mdx`:
- Line 409: Update the Helm values key to the governance-namespaced setting:
replace any use of bifrost.sourceOfTruth with bifrost.governance.sourceOfTruth
in the documentation text so it matches the governance.* structure used
elsewhere; ensure the example and explanatory sentence use
bifrost.governance.sourceOfTruth: "config.json" and adjust any neighboring
references in the same paragraph to maintain consistency with other governance
settings.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4cea6b8c-3004-4d7b-b947-351505d75347

📥 Commits

Reviewing files that changed from the base of the PR and between 8c263b3 and 99974c2.

📒 Files selected for processing (8)
  • docs/deployment-guides/helm/governance.mdx
  • docs/features/governance/complexity-router.mdx
  • framework/configstore/complexityconfig.go
  • framework/configstore/rdb.go
  • framework/configstore/rdb_test.go
  • framework/configstore/tables/config.go
  • transports/bifrost-http/lib/config.go
  • transports/bifrost-http/lib/config_test.go

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.

Files API Support

1 participant