Skip to content

fix(db): read defaultAssistant from config in createCodebase (fixes #1703)#1746

Merged
Wirasm merged 1 commit into
coleam00:devfrom
kagura-agent:fix/codebase-default-assistant
May 26, 2026
Merged

fix(db): read defaultAssistant from config in createCodebase (fixes #1703)#1746
Wirasm merged 1 commit into
coleam00:devfrom
kagura-agent:fix/codebase-default-assistant

Conversation

@kagura-agent
Copy link
Copy Markdown
Contributor

@kagura-agent kagura-agent commented May 22, 2026

Summary

  • Problem: createCodebase() hardcoded 'claude' as the fallback when ai_assistant_type was not provided, ignoring the user's configured defaultAssistant.
  • Why it matters: Users who set a non-claude default assistant (via DEFAULT_AI_ASSISTANT env var or ~/.archon/config.yaml) still got claude for every new project registration.
  • What changed: createCodebase() now checks process.env.DEFAULT_AI_ASSISTANT before falling back to 'claude', consistent with how getOrCreateConversation() resolves the default assistant.
  • What did not change: Explicit ai_assistant_type values are used directly. No API schema changes. No new imports.

UX Journey

Before

User                         Archon
────                         ──────
sets DEFAULT_AI_ASSISTANT=codex
registers project ──────────▶ createCodebase({name, cwd})
                              ai_assistant_type = 'claude' (hardcoded)
sees project uses claude ◀── env var ignored

After

User                         Archon
────                         ──────
sets DEFAULT_AI_ASSISTANT=codex
registers project ──────────▶ createCodebase({name, cwd})
                              ai_assistant_type = process.env.DEFAULT_AI_ASSISTANT → 'codex'
sees project uses codex ◀─── respects user's configured default

Architecture Diagram

No architectural changes. Single fallback chain updated: data.ai_assistant_type ?? process.env.DEFAULT_AI_ASSISTANT ?? 'claude'.

Label Snapshot

Label Value
Area db
Type Bug fix
Scope packages/core/src/db/codebases.ts

Change Metadata

Metric Value
Files changed 2
Lines added ~34
Lines removed ~2
New dependencies None

Linked Issue

Closes #1703

Validation Evidence

  • bun test packages/core/src/db/codebases.test.ts → 31 pass, 0 fail
  • bun run test (full suite) → 0 fail across all packages
  • eslint + prettier via lint-staged → clean

New tests:

  1. Reads DEFAULT_AI_ASSISTANT env var when ai_assistant_type omitted → uses codex
  2. Falls back to claude when no env var set
  3. Explicit ai_assistant_type takes priority over env var

Security Impact

None. Reads an existing env var that the server already uses elsewhere.

Compatibility/Migration

Backward compatible. Behavior is identical when DEFAULT_AI_ASSISTANT is unset (falls back to 'claude').

Human Verification

  • Tested with bun test (per-file and full suite)
  • Lint-staged passed

Risks and Mitigations

Risk Mitigation
Env var not set Falls back to 'claude' (same as before)

Side Effects/Blast Radius

None. Only affects the default assistant assignment in createCodebase().

Rollback Plan

Revert the single commit.

Summary by CodeRabbit

  • New Features

    • Assistant type selection now prefers an explicit value, then the DEFAULT_AI_ASSISTANT environment setting, and falls back to 'claude'.
  • Tests

    • Expanded tests to cover: env unset (falls back to 'claude'), env set (uses DEFAULT_AI_ASSISTANT when omitted), and explicit value overriding the env setting; environment isolation added to prevent cross-test leakage.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

📝 Walkthrough

Walkthrough

createCodebase now selects assistantType in this order: data.ai_assistant_type, then process.env.DEFAULT_AI_ASSISTANT, and finally 'claude'. Tests were updated/added to verify behavior when the env var is unset, set, and when an explicit ai_assistant_type overrides the env var.

Changes

Assistant Type Precedence

Layer / File(s) Summary
Compute assistantType from data → env → fallback
packages/core/src/db/codebases.ts
createCodebase now determines assistantType by preferring data.ai_assistant_type, then process.env.DEFAULT_AI_ASSISTANT, and using 'claude' only if both are absent.
Tests: env unset, env set, explicit override
packages/core/src/db/codebases.test.ts
Replaced the previous default test and added tests that (1) assert 'claude' is used when DEFAULT_AI_ASSISTANT is unset, (2) assert the env value is used when set and ai_assistant_type is omitted, and (3) assert an explicit ai_assistant_type overrides the env var. Each test manages process.env to avoid cross-test leakage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • coleam00/Archon#1729: Both PRs change how ai_assistant_type is determined during new codebase creation—this PR updates createCodebase's fallback precedence to include the env var, while that PR modifies adapters to supply a resolved ai_assistant_type at creation time.

Poem

🐰 I sniffed the env and read the file,
Prefer your choice, then DEFAULT for style,
If neither sings, 'claude' hops in neat,
Tests tidy trails so states don't meet,
A cheerful hop for code complete.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: reading defaultAssistant from config in createCodebase to fix issue #1703.
Description check ✅ Passed The description is comprehensive, covering problem statement, why it matters, what changed, UX journey, validation evidence, security impact, compatibility, and risks.
Linked Issues check ✅ Passed The PR fulfills the primary objective from #1703: createCodebase() now reads DEFAULT_AI_ASSISTANT environment variable before falling back to 'claude', matching the requested behavior.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue #1703; modifications to codebases.ts and codebases.test.ts implement the exact fix requested without introducing extraneous changes.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
packages/core/src/db/codebases.test.ts (1)

18-20: ⚡ Quick win

Prefer spyOn() over mock.module() for this internal module mock.

Line 18 uses mock.module() for ../config/config-loader; switch this to spyOn() + mockRestore() to avoid test isolation issues from module-level mocks.

As per coding guidelines, "Use spyOn() for internal modules that other test files import directly ... mock.module() cleanup does NOT work and should never be relied upon".

🤖 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 `@packages/core/src/db/codebases.test.ts` around lines 18 - 20, Replace the
module-level mock.module call that stubs loadConfig with a Jest spy so the mock
is properly scoped and cleaned up: use spyOn(...) to spy on the loadConfig
export (e.g., spyOn(require(...),
'loadConfig').mockImplementation(mockLoadConfig)) and then call mockRestore() in
an afterEach to restore the original implementation; specifically swap out the
mock.module usage for spyOn targeting loadConfig, keep using mockLoadConfig as
the implementation, and ensure mockRestore() runs after each test to prevent
cross-test pollution.
packages/core/src/db/codebases.ts (1)

22-30: ⚡ Quick win

Add explicit observability for config-load fallback.

Line 27 silently catches config-load failures and falls back to 'claude'. Please log a structured _failed event (and optionally a success _completed event) so fallback behavior is diagnosable in production.

As per coding guidelines, "**/*.ts: Use structured logging with Pino using event naming convention {domain}.{action}_{state}" and "Apply Fail Fast + Explicit Errors - ... never silently swallow errors ... document intentional fallback behavior with a comment".

🤖 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 `@packages/core/src/db/codebases.ts` around lines 22 - 30, The config-load
fallback for assistantType (variable assistantType set via loadConfig())
currently swallows errors; update the try/catch to log a structured Pino event
when loadConfig fails (e.g., using the module's logger instance such as
processLogger or logger) with an event name like "config.load_failed" and
include error details and context, and optionally emit "config.load_completed"
on success; also add a short comment above the catch documenting the intentional
fallback to 'claude' so the behavior is explicit.
🤖 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.

Nitpick comments:
In `@packages/core/src/db/codebases.test.ts`:
- Around line 18-20: Replace the module-level mock.module call that stubs
loadConfig with a Jest spy so the mock is properly scoped and cleaned up: use
spyOn(...) to spy on the loadConfig export (e.g., spyOn(require(...),
'loadConfig').mockImplementation(mockLoadConfig)) and then call mockRestore() in
an afterEach to restore the original implementation; specifically swap out the
mock.module usage for spyOn targeting loadConfig, keep using mockLoadConfig as
the implementation, and ensure mockRestore() runs after each test to prevent
cross-test pollution.

In `@packages/core/src/db/codebases.ts`:
- Around line 22-30: The config-load fallback for assistantType (variable
assistantType set via loadConfig()) currently swallows errors; update the
try/catch to log a structured Pino event when loadConfig fails (e.g., using the
module's logger instance such as processLogger or logger) with an event name
like "config.load_failed" and include error details and context, and optionally
emit "config.load_completed" on success; also add a short comment above the
catch documenting the intentional fallback to 'claude' so the behavior is
explicit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e99c1572-c78a-4b3d-83f6-3ebcad65a5c0

📥 Commits

Reviewing files that changed from the base of the PR and between aa71520 and 1d0c982.

📒 Files selected for processing (2)
  • packages/core/src/db/codebases.test.ts
  • packages/core/src/db/codebases.ts

…oleam00#1703)

createCodebase() hardcoded 'claude' as the fallback when ai_assistant_type
was not provided. Now checks process.env.DEFAULT_AI_ASSISTANT first,
consistent with how getOrCreateConversation() resolves the default.

Falls back to 'claude' only when both the parameter and env var are unset.
@kagura-agent kagura-agent force-pushed the fix/codebase-default-assistant branch from 1d0c982 to 6a16d37 Compare May 22, 2026 04:38
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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)
packages/core/src/db/codebases.test.ts (1)

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

Harden env-var cleanup to prevent cross-test leakage on failure paths.

process.env.DEFAULT_AI_ASSISTANT is mutated in-test and cleaned up only at the tail of the test body. If a test fails early, env state can leak into subsequent tests.

Suggested fix
 describe('codebases', () => {
+  let originalDefaultAssistant: string | undefined;
   beforeEach(() => {
     mockQuery.mockClear();
+    originalDefaultAssistant = process.env.DEFAULT_AI_ASSISTANT;
   });
+  afterEach(() => {
+    if (originalDefaultAssistant === undefined) {
+      delete process.env.DEFAULT_AI_ASSISTANT;
+    } else {
+      process.env.DEFAULT_AI_ASSISTANT = originalDefaultAssistant;
+    }
+  });
@@
     test('reads DEFAULT_AI_ASSISTANT env var when ai_assistant_type omitted', async () => {
       process.env.DEFAULT_AI_ASSISTANT = 'codex';
@@
       expect(mockQuery).toHaveBeenCalledWith(expect.any(String), expect.arrayContaining(['codex']));
-      delete process.env.DEFAULT_AI_ASSISTANT;
     });
@@
     test('explicit ai_assistant_type takes priority over env var', async () => {
       process.env.DEFAULT_AI_ASSISTANT = 'codex';
@@
       expect(mockQuery).toHaveBeenCalledWith(expect.any(String), expect.arrayContaining(['pi']));
-      delete process.env.DEFAULT_AI_ASSISTANT;
     });

As per coding guidelines, "Apply Determinism + Reproducibility - prefer reproducible commands and locked dependency behavior in CI-sensitive paths; keep tests deterministic with no flaky timing or network dependence without guardrails".

🤖 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 `@packages/core/src/db/codebases.test.ts` around lines 81 - 125, The tests
mutate process.env.DEFAULT_AI_ASSISTANT and only delete it at the end, risking
env leakage on failures; update the tests around createCodebase (the three tests
named 'defaults ai_assistant_type to claude...', 'reads DEFAULT_AI_ASSISTANT env
var when ai_assistant_type omitted', and 'explicit ai_assistant_type takes
priority over env var') to save the original value and restore it in a finally
block (or use beforeEach/afterEach) so process.env.DEFAULT_AI_ASSISTANT is
always reset even if the test throws; reference process.env.DEFAULT_AI_ASSISTANT
and the createCodebase call when implementing the safeguard.
🤖 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 `@packages/core/src/db/codebases.test.ts`:
- Around line 81-125: The tests mutate process.env.DEFAULT_AI_ASSISTANT and only
delete it at the end, risking env leakage on failures; update the tests around
createCodebase (the three tests named 'defaults ai_assistant_type to claude...',
'reads DEFAULT_AI_ASSISTANT env var when ai_assistant_type omitted', and
'explicit ai_assistant_type takes priority over env var') to save the original
value and restore it in a finally block (or use beforeEach/afterEach) so
process.env.DEFAULT_AI_ASSISTANT is always reset even if the test throws;
reference process.env.DEFAULT_AI_ASSISTANT and the createCodebase call when
implementing the safeguard.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a12bf020-eb07-4f54-a016-8fb9a3092f57

📥 Commits

Reviewing files that changed from the base of the PR and between 1d0c982 and 6a16d37.

📒 Files selected for processing (2)
  • packages/core/src/db/codebases.test.ts
  • packages/core/src/db/codebases.ts

@Wirasm
Copy link
Copy Markdown
Collaborator

Wirasm commented May 22, 2026

@kagura-agent this PR appears to fully address #1703. Consider adding Closes #1703 to the PR body so the issue auto-closes on merge.

@kagura-agent
Copy link
Copy Markdown
Contributor Author

Thanks for the review! The PR body already includes Closes #1703 so the issue should auto-close on merge. 👍

@Wirasm
Copy link
Copy Markdown
Collaborator

Wirasm commented May 25, 2026

Review Summary

Verdict: ready-to-merge

Clean addition of DEFAULT_AI_ASSISTANT env var support as a fallback in createCodebase(). The two new tests correctly cover the explicit-argument priority and env-var path. No bugs or CLAUDE.md violations found.

Suggested fixes

  • packages/core/src/db/codebases.ts:18: If DEFAULT_AI_ASSISTANT is set to "", the ?? chain stores an empty string in the DB instead of falling back to 'claude'. Consider adding a test case for this edge (compare conversations.ts:75 for the existing pattern).

  • packages/core/src/db/codebases.ts:18: Unlike conversations.ts:317-323, the codebases path does not validate that DEFAULT_AI_ASSISTANT is a registered provider. An invalid value silently lands in the DB. Consider adding validation or a comment documenting this.

Minor / nice-to-have

  • packages/core/src/db/codebases.test.ts: The new tests use delete process.env.DEFAULT_AI_ASSISTANT for cleanup but don't save/restore the original value. Adding beforeEach/afterEach (matching conversations.test.ts:32-41) would be more robust if test ordering changes in the future.

Compliments

  • Test hygiene is solid — env var cleanup is in place and conversations.test.ts correctly deletes the env var before asserting the hardcoded 'claude' default.
  • The pattern mirrors existing env-var testing in config-loader.test.ts, keeping the codebase consistent.

Reviewed via maintainer-review-pr workflow (Pi/Minimax). Aspects run: code-review, test-coverage.

@Wirasm
Copy link
Copy Markdown
Collaborator

Wirasm commented May 25, 2026

Review Summary

Verdict: minor-fixes-needed

This PR adds a DEFAULT_AI_ASSISTANT environment variable fallback for ai_assistant_type in createCodebase(), mirroring the existing pattern in conversations.ts. Implementation is clean and tests cover the main cases — but one edge case needs a decision before merging.

Blocking issues

(none)

Suggested fixes

  • packages/core/src/db/codebases.ts (env-var fallback): When process.env.DEFAULT_AI_ASSISTANT is an empty string, the nullish-coalescing chain passes '' to the SQL query instead of falling through to the 'claude' default. Either add an empty-string guard in the implementation ((envValue || undefined)) or add a test asserting the empty-string case is handled — and decide which behavior is intended.

Minor / nice-to-have

  • packages/core/src/db/codebases.test.ts: The new env-var tests use inline delete process.env.DEFAULT_AI_ASSISTANT cleanup. Consider adopting the beforeEach/afterEach save/restore pattern from conversations.test.ts — it's more resilient if a test throws before the cleanup line. The test file's first new test would also become self-contained without relying on global state being unset.

Compliments

  • Implementation correctly mirrors the established conversations.ts pattern.
  • Three new tests cover the env-var feature well (unset, set, override).

Reviewed via maintainer-review-pr workflow (Pi/Minimax). Aspects run: code-review, test-coverage.

@kagura-agent
Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review @Wirasm! Good catch on the empty-string edge case — I'll add an empty-string guard so '' falls through to the 'claude' default, and adopt the beforeEach/afterEach pattern for env var cleanup in the tests. Will push the fix shortly.

@Wirasm Wirasm merged commit ac18034 into coleam00:dev May 26, 2026
4 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.

feat(db): codebase ai_assistant_type should inherit defaultAssistant, not hardcode "claude"

2 participants