Skip to content

chore(config): freeze CodeIqConfig mutation surface (#49)#53

Merged
aksOps merged 2 commits into
mainfrom
cleanup/freeze-codeiq-config-setters
Apr 23, 2026
Merged

chore(config): freeze CodeIqConfig mutation surface (#49)#53
aksOps merged 2 commits into
mainfrom
cleanup/freeze-codeiq-config-setters

Conversation

@aksOps

@aksOps aksOps commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes follow-up task #49: eliminate the setter-mutation hazard on the Spring-singleton CodeIqConfig bean. Production code outside the io.github.randomcodespace.iq.config package can no longer mutate the bean.

Approach (Path 3 — package-relocate + tighten visibility)

Four production CLI sites were mutating the shared CodeIqConfig singleton after Spring startup, propagating state to every @Autowired consumer. Rather than a cascading architectural refactor (routing CLI flags through ConfigResolver.cliOverlay() — Phase-C work), this PR:

  1. Introduces CliStartupConfigOverrides in the iq.config package — a small, named, documented helper for the CLI startup phase with three entry points: applyServeOverrides, applyCacheDir, applyServiceName. Null/blank-safe.
  2. Migrates 4 production call sites (ServeCommand, CliOutput, EnrichCommand, Analyzer) to the helper.
  3. Drops public from every CodeIqConfig setter. External packages no longer compile against the mutation surface; future-drift is impossible without a deliberate helper extension.
  4. Adds CodeIqConfigTestSupport (test classpath only, iq.config package) so 15 test classes can keep constructing arbitrary per-test instances without scattering them across packages.

Commits

  • 6ea345e refactor(config): centralize CLI startup overrides in a config-package helper
  • c032373 refactor(config): tighten CodeIqConfig setter visibility to package-private

Tests

  • Before: 3272 pass / 0 fail / 31 skipped
  • After: 3278 pass / 0 fail / 31 skipped (+6 tests for the new helper)
  • 51 setter call sites across 15 test classes migrated to the fluent CodeIqConfigTestSupport.override(config).rootPath(x).done() API.

Notable

  • Analyzer.java:817 — a 4th mutation site not in the original brief, found via compile. Same semantic as CliOutput.setServiceName; routed through applyServiceName.
  • Test helper visibilityCodeIqConfigTestSupport lives in the test classpath only. Production code cannot import it.

Follow-ups (tracked)

Test plan

  • CI green
  • mvn -B test on merge commit reports 3278 pass
  • Smoke: code-iq serve <root> still correctly scopes to the given root
  • Smoke: code-iq enrich --cache-dir <path> <root> still writes cache to the given directory
  • Smoke: service-name propagation from indexing CLI flag → graph node tagging still works

🤖 Generated with Claude Code

aksOps added 2 commits April 23, 2026 12:45
…e helper

Collapse the four production call sites that mutate the CodeIqConfig Spring
singleton (ServeCommand, EnrichCommand, CliOutput, Analyzer) through a single
package-adjacent helper. This pins the "mutation happens once at CLI startup"
contract in one place and sets up a follow-up commit to tighten the bean's
setter visibility to package-private.

- New CliStartupConfigOverrides with applyServeOverrides / applyCacheDir /
  applyServiceName. Null/blank inputs are no-ops — never overwrite an
  in-code default with an absent value.
- Analyzer.runSmartWithCache now routes service-name propagation through
  the helper (same semantics, same guard condition).
- Six unit tests verify each helper mutates only the intended fields on a
  freshly-adapted CodeIqConfig and that null/blank inputs are no-ops.
…rivate

Drop `public` from every setter on CodeIqConfig and its Graph inner class.
Production mutation is now restricted at compile time to:
  - UnifiedConfigAdapter.toCodeIqConfig (once, at Spring startup)
  - CliStartupConfigOverrides (once per JVM, at CLI entry)

Both live in `io.github.randomcodespace.iq.config` and reach the
package-private setters directly. Every other code path — controllers,
MCP tools, background workers — loses the compile-time ability to mutate
the Spring singleton. This is the mutation hazard cleanup #49 called for.

Test migration:
- Two in-package tests (CodeIqConfigTest, GraphBootstrapperTest) keep
  working unchanged.
- 15 out-of-package test classes across `iq.api`, `iq.cli`,
  `iq.intelligence.*`, `iq.mcp`, `iq.query` are migrated to route setter
  calls through a new test-only helper CodeIqConfigTestSupport (lives in
  src/test/java/io/github/randomcodespace/iq/config/, so tests compile
  against the package-private setters). Fluent API keeps call sites
  readable: `CodeIqConfigTestSupport.override(config).rootPath(x).done();`
  The name makes the test-only intent unmistakable and the helper is not
  reachable from production code paths.
- 51 call sites rewritten; semantics preserved verbatim.

Full suite green: 3278 tests, 0 failures, 31 skipped (baseline unchanged).
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
70.7% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@aksOps aksOps merged commit 046ea70 into main Apr 23, 2026
8 of 9 checks passed
@aksOps aksOps deleted the cleanup/freeze-codeiq-config-setters branch April 26, 2026 05:52
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