fix(client): doctor --fix self-heal + factory-model wiki page #296

Merged
clawdie merged 3 commits from fix-doctor-self-heal into main 2026-06-29 07:27:22 +02:00
Owner

Two changes that share the doctor surface, combined per request.

Code: doctor --fix self-heal (fixes #294 bugs, refs #295)

1. Nested-runtime panic (crash)

fix_fixable spawned a fresh tokio::runtime::Runtime and block_ond cmd_upgrade from inside the #[tokio::main] runtime → panic "Cannot start a runtime from within a runtime" the moment a fixable check was found. Now async and awaits cmd_upgrade directly.

2. behind == 0 short-circuit (logic)

cmd_upgrade returned "already at latest" when at origin/main, but binary_vs_git_version fires when the binary is stale vs the source — orthogonal to being behind. New force flag: doctor --fix rebuilds + reinstalls regardless; plain colibri upgrade keeps the early return.

Supporting (needed for 2 to actually work)

  • build.rs now watches .git/refs/tags — a tag created after the last build (osa's case) lands in .git/refs/tags not packed-refs, so without this the force rebuild re-bakes the same stale COLIBRI_GIT_DESCRIBE.
  • behind-count pinned to origin/main (was @{u}) to match the pull target.

Docs: factory-model wiki page

New docs/wiki/factory-model.md mapping Colibri to the Kaggle "New SDLC" whitepaper (harness, spectrum, conductor/orchestrator, economics), plus index entry. Review corrections folded in:

  • dropped two non-existent MCP tool names (mother-build, geodesic-dome) and the unverifiable colibri-factory-model skill reference — neither exists in the repo, the exact drift this wiki prevents;
  • prefixed doctor.md's doctor.rs references with crates/ (pre-existing wiki-lint FAIL that blocked --strict).

Gates

  • cargo fmt --all --check clean; cargo clippy -p colibri-client --all-targets -- -D warnings clean
  • wiki-lint 195 PASS / 0 FAIL; prettier clean

Out of scope (stays in #295): no-rollback-on-failed-start, redundant triple fetch, stale-agent prune dispatch target.

Refs #295.

🤖 Generated with Claude Code

Two changes that share the doctor surface, combined per request. ## Code: `doctor --fix` self-heal (fixes #294 bugs, refs #295) ### 1. Nested-runtime panic (crash) `fix_fixable` spawned a fresh `tokio::runtime::Runtime` and `block_on`d `cmd_upgrade` from inside the `#[tokio::main]` runtime → panic *"Cannot start a runtime from within a runtime"* the moment a fixable check was found. Now `async` and awaits `cmd_upgrade` directly. ### 2. `behind == 0` short-circuit (logic) `cmd_upgrade` returned "already at latest" when at `origin/main`, but `binary_vs_git_version` fires when the *binary* is stale vs the *source* — orthogonal to being behind. New `force` flag: `doctor --fix` rebuilds + reinstalls regardless; plain `colibri upgrade` keeps the early return. ### Supporting (needed for 2 to actually work) - `build.rs` now watches `.git/refs/tags` — a tag created after the last build (osa's case) lands in `.git/refs/tags` not `packed-refs`, so without this the force rebuild re-bakes the *same* stale `COLIBRI_GIT_DESCRIBE`. - behind-count pinned to `origin/main` (was `@{u}`) to match the pull target. ## Docs: factory-model wiki page New `docs/wiki/factory-model.md` mapping Colibri to the Kaggle "New SDLC" whitepaper (harness, spectrum, conductor/orchestrator, economics), plus index entry. Review corrections folded in: - dropped two non-existent MCP tool names (`mother-build`, `geodesic-dome`) and the unverifiable `colibri-factory-model` skill reference — neither exists in the repo, the exact drift this wiki prevents; - prefixed `doctor.md`'s `doctor.rs` references with `crates/` (pre-existing wiki-lint FAIL that blocked `--strict`). ## Gates - `cargo fmt --all --check` clean; `cargo clippy -p colibri-client --all-targets -- -D warnings` clean - `wiki-lint` 195 PASS / 0 FAIL; prettier clean Out of scope (stays in #295): no-rollback-on-failed-start, redundant triple fetch, stale-agent prune dispatch target. Refs #295. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(client): doctor --fix self-heal — drop nested runtime, force stale-binary rebuild
Some checks failed
CI / rust (pull_request) Has been cancelled
CI / markdown (pull_request) Has been cancelled
CI / port (pull_request) Has been cancelled
CI / agent-jail-pkgs (pull_request) Has been cancelled
0b37e1cd39
Two bugs in #294 made `colibri doctor --fix` non-functional on first real use.

1. Nested-runtime panic: fix_fixable spawned a fresh tokio Runtime and
   block_on'd cmd_upgrade from inside the #[tokio::main] runtime, panicking
   "Cannot start a runtime from within a runtime" the moment a fixable check
   was found. Made fix_fixable async and await cmd_upgrade directly.

2. behind==0 short-circuit: cmd_upgrade returned "already at latest" when the
   checkout was at origin/main, but binary_vs_git_version fires when the binary
   is stale vs the source — orthogonal to being behind. Added a force flag so
   doctor --fix rebuilds and reinstalls regardless of behind-count; plain
   `colibri upgrade` keeps the early return.

Also: build.rs now watches .git/refs/tags so a tag created after the last build
re-bakes COLIBRI_GIT_DESCRIBE (otherwise the force rebuild would re-bake the
same stale version); behind-count pinned to origin/main to match the pull
target instead of @{u}.

Refs #295.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Maps Colibri to the Kaggle whitepaper frameworks: factory metaphor,
Agent=Model+Harness, vibe-coding-to-agentic-engineering spectrum,
conductor/orchestrator modes, context engineering, economics.

Closes Gap 8 (architecture docs don't name the factory model).
Cross-linked from wiki index.
docs(wiki): factory model — fix fabricated tool/skill refs, repair doctor.md drift
Some checks failed
CI / rust (pull_request) Has been cancelled
CI / markdown (pull_request) Has been cancelled
CI / port (pull_request) Has been cancelled
CI / agent-jail-pkgs (pull_request) Has been cancelled
1e3c18bbb1
Drop two non-existent MCP tool names (mother-build, geodesic-dome) from the
factory metaphor table and the unverifiable colibri-factory-model skill
reference — neither exists in the repo, the exact drift this wiki prevents.
Also prefix doctor.md's doctor.rs references with crates/ so wiki-lint passes
(was a pre-existing FAIL blocking --strict).

wiki-lint: 195 PASS / 0 FAIL; prettier clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
clawdie changed title from fix(client): doctor --fix self-heal — drop nested runtime, force stale-binary rebuild to fix(client): doctor --fix self-heal + factory-model wiki page 2026-06-29 07:26:19 +02:00
clawdie deleted branch fix-doctor-self-heal 2026-06-29 07:27:25 +02:00
Author
Owner

Live verification request — osa (FreeBSD)

This PR is merged but unproven on the host it was built for. Please run the check below and report the doctor output before/after.

Phase 1 — deploy the fix (safe; does not touch the buggy --fix path)

cd <colibri checkout>
git pull --ff-only origin main      # main is ahead, so this is a normal upgrade
colibri upgrade --yes               # old binary, but plain upgrade never calls fix_fixable → no panic
colibri doctor                      # binary_vs_git_version should now be PASS (describe starts with v0.12.0)

Phase 2 — prove doctor --fix self-heals (the two bugs)
The decisive case is a stale binary at HEAD (behind == 0) — exactly osa''s original state. To reproduce deterministically after Phase 1:

# bake an older version into the installed binary while source stays at HEAD
git stash list >/dev/null            # ensure clean tree
sudo cp /usr/local/bin/colibri-daemon /usr/local/bin/colibri-daemon.bak
# install a deliberately stale daemon: build from an older describe, or restore a pre-v0.12.0 binary if you have one
# then:
colibri doctor                       # expect binary_vs_git_version = WARN, fixable=true
colibri doctor --fix                 # <-- the test

Expected with the fix:

  • No panic (bug 1 was "Cannot start a runtime from within a runtime").
  • Despite behind == 0, it prints source at latest; rebuilding to refresh installed binary, rebuilds, swaps, restarts (bug 2 force path).
  • Re-run doctor shows binary_vs_git_versionPASS.

If you can''t easily stage a stale binary, the minimum useful signal is: run colibri doctor --fix on any state and confirm it completes without panicking — the old binary aborts the moment it finds a fixable check.

Please paste: colibri doctor before, the --fix run output, and colibri doctor after. Refs #295.

### Live verification request — osa (FreeBSD) This PR is merged but unproven on the host it was built for. Please run the check below and report the doctor output before/after. **Phase 1 — deploy the fix (safe; does not touch the buggy --fix path)** ```sh cd <colibri checkout> git pull --ff-only origin main # main is ahead, so this is a normal upgrade colibri upgrade --yes # old binary, but plain upgrade never calls fix_fixable → no panic colibri doctor # binary_vs_git_version should now be PASS (describe starts with v0.12.0) ``` **Phase 2 — prove `doctor --fix` self-heals (the two bugs)** The decisive case is a **stale binary at HEAD (behind == 0)** — exactly osa''s original state. To reproduce deterministically after Phase 1: ```sh # bake an older version into the installed binary while source stays at HEAD git stash list >/dev/null # ensure clean tree sudo cp /usr/local/bin/colibri-daemon /usr/local/bin/colibri-daemon.bak # install a deliberately stale daemon: build from an older describe, or restore a pre-v0.12.0 binary if you have one # then: colibri doctor # expect binary_vs_git_version = WARN, fixable=true colibri doctor --fix # <-- the test ``` Expected with the fix: - **No panic** (bug 1 was "Cannot start a runtime from within a runtime"). - Despite `behind == 0`, it prints `source at latest; rebuilding to refresh installed binary`, rebuilds, swaps, restarts (bug 2 force path). - Re-run doctor shows `binary_vs_git_version` → **PASS**. If you can''t easily stage a stale binary, the minimum useful signal is: run `colibri doctor --fix` on any state and confirm it **completes without panicking** — the old binary aborts the moment it finds a fixable check. Please paste: `colibri doctor` before, the `--fix` run output, and `colibri doctor` after. Refs #295.
Author
Owner

Supersedes the stale-binary test above — clean end-to-end upgrade

The earlier note tried to stage a stale binary, which is awkward. Instead, main is now 0.13.0-dev (tag v0.13.0-dev, #299), giving a real version delta to upgrade across. On osa:

cd <colibri checkout>
colibri upgrade --check     # expect: N commit(s) behind origin/main
colibri upgrade --yes       # pull → cargo build --release → stop → swap → start → verify
colibri doctor              # expect: binary_vs_git_version PASS, version 0.13.0-dev

This exercises the full pipeline (git-behind detection → build → binary swap → service restart → post-restart doctor verify) with a legible 0.12.0 → 0.13.0-dev before/after.

The doctor --fix panic (bug 1) is already confirmed dead from your earlier run (two doctor passes, no "runtime from within a runtime"). This run covers the upgrade path itself. Please paste upgrade --check, the --yes output, and doctor after.

### Supersedes the stale-binary test above — clean end-to-end upgrade The earlier note tried to stage a stale binary, which is awkward. Instead, main is now `0.13.0-dev` (tag `v0.13.0-dev`, #299), giving a real version delta to upgrade across. On osa: ```sh cd <colibri checkout> colibri upgrade --check # expect: N commit(s) behind origin/main colibri upgrade --yes # pull → cargo build --release → stop → swap → start → verify colibri doctor # expect: binary_vs_git_version PASS, version 0.13.0-dev ``` This exercises the full pipeline (git-behind detection → build → binary swap → service restart → post-restart doctor verify) with a legible 0.12.0 → 0.13.0-dev before/after. The `doctor --fix` panic (bug 1) is already confirmed dead from your earlier run (two doctor passes, no "runtime from within a runtime"). This run covers the upgrade path itself. Please paste `upgrade --check`, the `--yes` output, and `doctor` after.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
clawdie/colibri!296
No description provided.