Skip to content

feat: raid doctor runs verify entries with self-heal (closes #42)#87

Merged
8bitAlex merged 2 commits into
mainfrom
feat/issue-42-doctor-verify
May 13, 2026
Merged

feat: raid doctor runs verify entries with self-heal (closes #42)#87
8bitAlex merged 2 commits into
mainfrom
feat/issue-42-doctor-verify

Conversation

@8bitAlex
Copy link
Copy Markdown
Owner

Summary

Closes #42. Builds on the verify-block schema work in #86.

raid doctor now executes every verify: entry on the active profile and per-repo raid.yaml files and surfaces each as its own finding:

Outcome Severity Meaning
First-try pass ok tasks: exited cleanly on the first attempt
Remediated warn tasks: failed, onFail: ran and recovered, retry of tasks: passed. Worth knowing — the precondition holds now, but didn't on the first try
Failed error No onFail:, or onFail: itself failed, or the retry of tasks: still failed. The underlying error message is included

A failure on one entry doesn't short-circuit subsequent entries — one raid doctor run reports the full picture.

  • RunVerify(v) (VerifyOutcome, error) now returns a tri-state outcome so doctor can distinguish a clean pass from a successful self-heal. VerifyOutcome and its constants are re-exported through src/raid.
  • checkVerify(label, entries) lives in doctor.go and is called by both checkProfile() (for profile-level verify:) and checkRepo() (for repo-level verify:).
  • JSON output is unchanged — verify findings flow through the existing Finding type, severity-encoded as \"ok\"/\"warn\"/\"error\".

Profile and repo templates now describe the tri-state semantics; schema reference + doctor usage docs explain how doctor reports verify entries and warn that doctor invokes the real tasks: shell commands.

Test plan

  • go test ./... -race — all packages green
  • New RunVerify outcome assertions in src/internal/lib/verify_test.go (passes, fails-without-onFail, remediation-succeeds, remediation-fails, second-pass-fails, empty-tasks no-op)
  • New checkVerify tests in src/internal/lib/doctor_test.go: passing → ok, remediated → warn, failed → error, zero entries skipped, failures don't short-circuit, empty list is no-op
  • Integration tests: TestCheckProfile_runsProfileLevelVerify (mixed pass/fail at the profile level), TestCheckRepo_runsRepoLevelVerify (repo-level verify)
  • verify.go + checkVerify at 100% line coverage (per-package run); project coverage 92.9%
  • cd site && npm run build — no broken links
  • Schema reference, doctor usage page, what's-new entry, repo + profile templates updated

🤖 Generated with Claude Code

Every verify: entry on the active profile and per-repo raid.yaml files
now runs as part of `raid doctor` and produces a finding:

  - first-try pass         → ok
  - failure → onFail → pass → warn (remediated by onFail)
  - failure that can't be healed → error

RunVerify now returns (VerifyOutcome, error) so doctor can distinguish
a clean pass from a successful self-heal — the latter is a warning so
the user knows something silently fixed itself. The remediated state
maps to the doctor warn severity; failures don't short-circuit
subsequent entries, so one run reports the full picture.

The cmd/doctor JSON shape is unchanged — verify findings flow through
the existing Finding type.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 13, 2026 21:29
@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

❌ Patch coverage is 90.74074% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.17%. Comparing base (a13ba7f) to head (75876c6).

Files with missing lines Patch % Lines
src/internal/lib/doctor.go 91.30% 3 Missing and 1 partial ⚠️
src/raid/raid.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #87      +/-   ##
==========================================
- Coverage   92.33%   92.17%   -0.17%     
==========================================
  Files          37       37              
  Lines        3380     3423      +43     
==========================================
+ Hits         3121     3155      +34     
- Misses        168      175       +7     
- Partials       91       93       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR wires verify: execution into raid doctor, extending health checks to run profile/repo precondition entries and report tri-state outcomes.

Changes:

  • Adds VerifyOutcome and updates RunVerify to return OK/remediated/failed outcomes.
  • Adds doctor-side verify finding generation and tests for outcome mapping.
  • Updates templates and docs to describe doctor verify behavior.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/resources/repo-template Updates repo template verify guidance for doctor execution.
src/resources/profile-template Updates profile template verify guidance for doctor execution.
src/raid/raid.go Re-exports VerifyOutcome and updated RunVerify signature.
src/internal/lib/verify.go Adds tri-state verify outcomes.
src/internal/lib/verify_test.go Updates verify tests to assert outcomes.
src/internal/lib/doctor.go Runs verify entries and converts outcomes into doctor findings.
src/internal/lib/doctor_test.go Adds doctor verify tests.
site/docs/whats-new.mdx Adds release note for doctor verify execution.
site/docs/usage/doctor.mdx Documents doctor verify findings and behavior.
site/docs/references/schema.mdx Updates schema reference text for verify doctor integration.
Comments suppressed due to low confidence (4)

src/internal/lib/doctor.go:217

  • Verify tasks are executed without applying the same default working-directory handling used by install tasks (withDefaultDir(..., home) for profile tasks and withDefaultDir(..., repoPath) for repo tasks). Any Shell verify entry that omits path will run from the doctor process's current directory, which can make relative checks/remediation pass or fail against the wrong location.
		outcome, err := RunVerify(v)

src/internal/lib/doctor.go:217

  • raid doctor now executes arbitrary verify tasks and onFail remediation here, so this path can mutate the workspace or raid vars, but it is not run under WithMutationLock like other task-executing/mutating commands (for example install/env/user commands). Concurrent doctor/install/env invocations can now race on the same files or ~/.raid/vars; acquire the mutation lock around verify execution or the doctor command.
		outcome, err := RunVerify(v)

src/internal/lib/doctor.go:217

  • Running verify tasks here lets their stdout/stderr go through the global command output writers (defaulting to os.Stdout/os.Stderr). Because the doctor CLI calls raid.Doctor() before encoding --json, any verify command that prints to stdout will prepend arbitrary text to the JSON response and make it unparsable; doctor should capture or redirect task output while collecting findings.
		outcome, err := RunVerify(v)

src/internal/lib/doctor.go:217

  • Verify entries can contain any task type, including Prompt and Confirm, and RunVerify executes them unfiltered. That makes raid doctor block waiting for stdin when a verify block contains an interactive task, which breaks doctor’s one-shot/non-interactive contract; reject or skip interactive task types for verify execution in doctor.
		outcome, err := RunVerify(v)

Message: "valid",
})

findings = append(findings, checkVerify(fmt.Sprintf("repo/%s verify", repo.Name), repo.Verify)...)
Comment on lines +497 to +502
repo := Repo{
Name: "r",
Path: dir,
URL: "http://example.com/r.git",
Verify: []Verify{{Name: "hello", Tasks: []Task{{Type: Shell, Cmd: "exit 0"}}}},
}
Comment thread src/internal/lib/verify.go Outdated
Comment on lines +39 to +41
// VerifyOutcome distinguishes a first-try pass from a successful
// self-heal. Doctor maps these to OK / warn severities; a fourth state
// (failed) is conveyed by RunVerify's error return.
Comment thread site/docs/usage/doctor.mdx Outdated
Comment on lines +44 to +45
:::warning Verify tasks execute real commands
Doctor invokes the actual `tasks:` and `onFail:` shell commands you've defined. Keep verify checks small, fast, and side-effect-light (a `node --version` probe, a `test -f`, a `Wait` against a local port). Heavy bootstrap work belongs in `install:`.
Comment thread site/docs/whats-new.mdx Outdated
## 0.14.0 — upcoming

**Declarative `verify:` blocks.** Profiles and per-repo `raid.yaml`s now accept a top-level `verify:` list. Each entry runs `tasks:` to assert a precondition (a tool is installed, a port is reachable, a credentials file exists), and an optional `onFail:` remediation gets exactly one chance to fix things — if it succeeds, raid re-runs `tasks:` once and the verify is reported as remediated; otherwise it surfaces as a structured `VERIFY_FAILED` error. Verify entries share execution context with `install:` tasks (active env + raid vars + task options). `raid doctor` integration to surface verify entries as health-report findings follows in [#42](https://github.com/8bitAlex/raid/issues/42). See [Schema → Verify](/docs/references/schema#verify). Closes [#38](https://github.com/8bitAlex/raid/issues/38).
**`raid doctor` runs `verify:` entries with self-heal.** Every `verify:` entry on the active profile and per-repo `raid.yaml` files now runs as part of `raid doctor` and produces its own finding: `ok` for a first-try pass, `warn` when the optional `onFail:` block recovered a failing precondition (the verify holds *now*, but didn't before — worth knowing), and `error` when the precondition can't be made to hold. Failures don't short-circuit subsequent entries, so a single `raid doctor` run reports the full picture. Doctor invokes the actual `tasks:` shell commands — keep verify checks small and fast, since they'll run every time you (or CI, or an agent) checks raid's health. See [Doctor → Verify entries](/docs/usage/doctor#verify-entries). Closes [#42](https://github.com/8bitAlex/raid/issues/42).
Declarative precondition checks. Each entry runs `tasks:` to assert that a dependency or environmental requirement is in place. An optional `onFail:` remediation gets exactly one chance to fix things — if remediation succeeds, raid re-runs `tasks:` once; if that pass succeeds the verify is reported as remediated, otherwise it fails.

Verify entries are accepted on both profiles and per-repo `raid.yaml` files. They share execution context with `install:` — the active environment, raid vars, and task options all apply. The schema accepts verify entries today; a future release will surface them through `raid doctor` (and, longer-term, a dedicated `raid verify` command).
Verify entries are accepted on both profiles and per-repo `raid.yaml` files. They share execution context with `install:` — the active environment, raid vars, and task options all apply. `raid doctor` runs every verify entry and surfaces each as a finding: a first-try pass is an `ok` finding, a successful self-heal is a `warn` (the precondition holds now, but didn't before — worth knowing), and a failure is an `error` carrying the underlying task error.
- doctor: load per-repo raid.yaml verify entries before running them.
  Previously the doctor path never invoked buildRepo/ExtractRepo on the
  repo, so verify blocks defined only in raid.yaml were silently skipped
  (BuildSingleRepoProfile keeps only name/path/branch; ExtractProfile
  only sees what's in the wrapping profile).
- verify: fix VerifyOutcome doc comment — describe the real tri-state
  enum rather than implying failed is a separate "fourth state".
- docs: clarify that verify tasks/onFail can be any task type
  (HTTP, Git, Template, Prompt/Confirm, SetVar, …), not just shell.
  Updates doctor.mdx warning, whats-new.mdx release note, and the
  embedded verifyArray schema description (which still said verify
  entries were inert / doctor integration was future work).
- tests: replace the pre-populated repo.Verify test with one that
  exercises the load-from-raid.yaml path, and add a merge case that
  covers both profile-level and raid.yaml verify entries.

Co-Authored-By: Copilot <copilot@github.com>
@8bitAlex
Copy link
Copy Markdown
Owner Author

Auto-review by meeseeks

Updates pushed: 1 commit

  • 75876c6 fix: address Copilot review on doctor verify

Copilot comments addressed: 6 of 6

  • doctor.go:192 — doctor now calls ExtractRepo to load per-repo raid.yaml verify entries before running them; without this BuildSingleRepoProfile's synthesized repo (name/path/branch only) skipped raid.yaml-only verify blocks.
  • doctor_test.go:502 — replaced the pre-populated repo.Verify test with TestCheckRepo_loadsVerifyFromRaidYaml (empty Verify, entry only in raid.yaml), and added TestCheckRepo_mergesProfileAndRaidYamlVerify to cover the merge case.
  • verify.go:41 — rewrote the VerifyOutcome doc comment to describe the real tri-state enum (OK / Remediated / Failed) instead of implying Failed is a separate "fourth state".
  • doctor.mdx:45 — warning now describes verify as any task type raid supports (HTTP, Git, Template, Prompt/Confirm, SetVar, …), not shell-only.
  • whats-new.mdx:14 — same clarification on the 0.14.0 release note.
  • schema.mdx:214 — fixed the embedded verifyArray description in schemas/raid-defs.schema.json (the mdx itself was already up to date — the stale text lived in the JSON schema description that the mdx mirrors).

Skipped: 0

Codecov patch: 90.74% (project 92.17%) — within 8pt (gap 1.43pt, well under the 8pt tolerance), acceptable.
Other CI: green — all build, docs, version-check, and CodeQL jobs passed.

@8bitAlex 8bitAlex merged commit d8b7a65 into main May 13, 2026
11 of 13 checks passed
@8bitAlex 8bitAlex deleted the feat/issue-42-doctor-verify branch May 13, 2026 23:49
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.

Polished doctor output — formatting, fix hints, summary

2 participants