Skip to content

fix(cli): surface generation-phase embedder degradation - #1851

Open
sloemo01 wants to merge 1 commit into
repowise-dev:mainfrom
sloemo01:fix/gen-embedder-degrade
Open

fix(cli): surface generation-phase embedder degradation#1851
sloemo01 wants to merge 1 commit into
repowise-dev:mainfrom
sloemo01:fix/gen-embedder-degrade

Conversation

@sloemo01

Copy link
Copy Markdown
Contributor

Fixes #1369.

Problem

The init header probes build_embedder and warns on degradation, but the generation phase rebuilds the embedder in run_repo_generation. If that second build fails — Ollama stops mid-run, an API key is revoked between the header probe and generation — the run writes mock (keyless) vectors with no record in state.json, so a scripted/agent run exits 0 and records a clean index despite having no semantic search.

Approach

Record the degradation on result in the shared generation entry (init_cmd/generation.py), then fold it into the persisted degraded list in both init flows:

  • Single-repo (command.py): appended to run_warnings, which flows into state.json["degraded"] (and save_full_state_and_config).
  • Workspace (workspace.py): written into the per-repo state.json degraded key.

mock stays silent — reaching the keyless default is not a failure.

Test

Added TestGenerationPhaseEmbedderDegradation in test_init_failure_reporting.py:

  • a real backend (ollama) that degrades to KeylessEmbedder records result.embedder_degraded;
  • mock default stays silent;
  • a healthy rebuild stays silent.

Verified the regression test fails without the fix (sabotage run).

Risk

Low. Only adds a result attribute and two glue lines; no behavior change for healthy or keyless-default runs. Full CLI unit suite: 2192 passed (1 pre-existing platform-baseline failure unrelated to this change).

Exclusions

Ollama down at embed time (not build time) is already surfaced by the existing per-page stub-fallback reporting; this closes the build-time gap the issue describes.

The init header probes the embedder and warns on degradation, but the
generation phase rebuilds it. If that second build fails (Ollama stops
mid-run, a key is revoked between header and generation), the run writes
mock (keyless) vectors and a scripted run records a clean state.json
with nothing saying so.

Record the degradation on result in run_repo_generation (the shared
generation entry) and fold it into the persisted 'degraded' list in both
the single-repo and workspace init flows, so a degraded generation-phase
embedder is reported exactly like a header-probe degradation.

mock stays silent: reaching the keyless default is not a failure.
@repowise-bot

repowise-bot Bot commented Aug 22, 2026

Copy link
Copy Markdown

✅ Health of changed files: 2.3 → 2.5 (+0.2)
⚠️ Change risk: moderate, riskier than 36% of this repo's commits.

📋 At a glance
1 file changed health · 4 hotspots touched · 3 co-change pairs left out · 4 files with recent fix history.

Files & modules (2)
  • packages (3 files)
    • .../init_cmd/workspace.py
    • .../init_cmd/command.py
    • .../init_cmd/generation.py
  • tests (1 file)
    • .../cli/test_init_failure_reporting.py

✅ Health gate: passed

📌 Before you merge

  • Run .../cli/test_edenai_reachability.py, .../cli/test_editor_setup.py, .../cli/test_health_rescore_gate.py, .../cli/test_file_page_volume_prompt.py (+2 more): they import the changed files
  • .../cli/helpers.py changed together with .../init_cmd/command.py in 13 past commits and isn't in this PR
  • .../ui/mode_selection.py changed together with .../init_cmd/command.py in 12 past commits and isn't in this PR
  • .../update_cmd/command.py changed together with .../init_cmd/command.py in 10 past commits and isn't in this PR
  • Docs that usually track this code: docs/reference/CLI_REFERENCE.md
🔎 More signals (3)

🗺️ Change map

flowchart LR
  subgraph PR ["Changed in this PR (3 with dependents)"]
    f_packages_cli_src_repowise_cli_commands_init_cmd_command_py[".../init_cmd/command.py 🔥"]:::changed
    f_packages_cli_src_repowise_cli_commands_init_cmd_generation_py[".../init_cmd/generation.py 🔥"]:::changed
    f_packages_cli_src_repowise_cli_commands_init_cmd_workspace_py[".../init_cmd/workspace.py 🔥"]:::changed
  end
  f_packages_cli_src_repowise_cli_commands_doctor_cmd_repo_checks_py[".../doctor_cmd/repo_checks.py"]
  f_packages_cli_src_repowise_cli_commands_init_cmd_command_py --> f_packages_cli_src_repowise_cli_commands_doctor_cmd_repo_checks_py
  f_packages_cli_src_repowise_cli_commands_generate_cmd_command_py[".../generate_cmd/command.py"]
  f_packages_cli_src_repowise_cli_commands_init_cmd_command_py --> f_packages_cli_src_repowise_cli_commands_generate_cmd_command_py
  f_packages_cli_src_repowise_cli_commands_hook_cmd_py[".../commands/hook_cmd.py"]
  f_packages_cli_src_repowise_cli_commands_init_cmd_command_py --> f_packages_cli_src_repowise_cli_commands_hook_cmd_py
  f_packages_cli_src_repowise_cli_commands_init_cmd___init___py[".../init_cmd/__init__.py"]
  f_packages_cli_src_repowise_cli_commands_init_cmd_command_py --> f_packages_cli_src_repowise_cli_commands_init_cmd___init___py
  f_packages_cli_src_repowise_cli_commands_init_cmd_generation_py --> f_packages_cli_src_repowise_cli_commands_generate_cmd_command_py
  f_packages_cli_src_repowise_cli_commands_init_cmd_generation_py --> f_packages_cli_src_repowise_cli_commands_init_cmd___init___py
  f_packages_cli_src_repowise_cli_commands_upgrade_flow_py[".../commands/upgrade_flow.py"]
  f_packages_cli_src_repowise_cli_commands_init_cmd_generation_py --> f_packages_cli_src_repowise_cli_commands_upgrade_flow_py
  f_packages_cli_src_repowise_cli_commands_init_cmd_workspace_py --> f_packages_cli_src_repowise_cli_commands_generate_cmd_command_py
  f_packages_cli_src_repowise_cli_commands_init_cmd_workspace_py --> f_packages_cli_src_repowise_cli_commands_init_cmd___init___py
  w_packages_cli_src_repowise_cli_helpers_py(["⚠️ .../cli/helpers.py changed together 13×, not in PR"]):::warn
  f_packages_cli_src_repowise_cli_commands_init_cmd_command_py -.- w_packages_cli_src_repowise_cli_helpers_py
  w_packages_cli_src_repowise_cli_ui_mode_selection_py(["⚠️ .../ui/mode_selection.py changed together 12×, not in PR"]):::warn
  f_packages_cli_src_repowise_cli_commands_init_cmd_command_py -.- w_packages_cli_src_repowise_cli_ui_mode_selection_py
  t_tests_unit_cli_test_edenai_reachability_py(["✅ .../cli/test_edenai_reachability.py"]):::guard
  t_tests_unit_cli_test_edenai_reachability_py -.-> f_packages_cli_src_repowise_cli_commands_init_cmd_command_py
  t_tests_unit_cli_test_file_page_volume_prompt_py(["✅ .../cli/test_file_page_volume_prompt.py"]):::guard
  t_tests_unit_cli_test_file_page_volume_prompt_py -.-> f_packages_cli_src_repowise_cli_commands_init_cmd_generation_py
  t_tests_unit_cli_test_workspace_deterministic_py(["✅ .../cli/test_workspace_deterministic.py"]):::guard
  t_tests_unit_cli_test_workspace_deterministic_py -.-> f_packages_cli_src_repowise_cli_commands_init_cmd_workspace_py
  classDef changed fill:#dbeafe,stroke:#1d4ed8,color:#1e3a5f
  classDef warn fill:#fef3c7,stroke:#b45309,color:#78350f
  classDef guard fill:#dcfce7,stroke:#15803d,color:#14532d
Loading

Solid arrows: code that imports the changed files (5 direct dependents, from the last indexed snapshot). Dashed: history/tests.

🔥 Hotspots touched (4)

  • .../init_cmd/workspace.py: 31 commits/90d, 5 dependents · primary owner: Raghav Chamadiya (90%)
  • .../cli/test_init_failure_reporting.py: 5 commits/90d, 0 dependents · primary owner: Akshat malik (49%)
  • .../init_cmd/command.py: 54 commits/90d, 8 dependents · primary owner: Raghav Chamadiya (92%)
1 more
  • .../init_cmd/generation.py: 19 commits/90d, 7 dependents · primary owner: Raghav Chamadiya (85%)

🔗 Hidden coupling (1 file)

  • .../init_cmd/command.py co-changes with these files (not in this PR):
    • .../cli/helpers.py (13×, 🟡 notable)
    • .../ui/mode_selection.py (12×, 🟡 notable)
    • .../update_cmd/command.py (10×, 🟡 notable)

👀 Suggested reviewers @RaghavChamadiya


📊 See the full report for this PR
Your repo map with this PR's blast radius lit up, every caller of the contracts it changes, and health before and after. No sign-in. · ⭐ Star Repowise · 📥 Install bot · Silence on a single PR with [skip repowise] in the title · Per-repo toggle on repowise.dev/settings?tab=bot · Updated 2026-08-22 14:48 UTC

@Ayush7614 Ayush7614 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.

Verified diff: packages/cli/src/repowise/cli/commands/init_cmd/generation.py:1 records build-time degradation to result.embedder_degraded and folds into state.json degraded for both single-repo (command.py) and workspace (workspace.py) flows, as described for #1369. mock stays silent correctly. Dedicated regression tests in test_init_failure_reporting.py verify degraded vs healthy vs mock. Low risk, honest fix — LGTM, no fake content.

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.

cli: init generation-phase embedder degradation can still go silent after a clean header probe

2 participants