Skip to content

Fix install funnel: prune guard, legacy config, doctor day-one failures - #116

Merged
yourconscience merged 1 commit into
mainfrom
fix/funnel
Jul 17, 2026
Merged

Fix install funnel: prune guard, legacy config, doctor day-one failures#116
yourconscience merged 1 commit into
mainfrom
fix/funnel

Conversation

@yourconscience

@yourconscience yourconscience commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Fixes for all findings from the VPS e2e funnel test (docs/plans/launch-2026-07-14/07-vps-e2e-funnel.md):

F1 (critical, data loss): setup-driven sync now previews per-harness removals and agent-role overwrites and asks per harness ([y/N], default no). Declining keeps the harness's existing files; adds and skill updates still apply. Steady-state dotagents sync behavior is unchanged.

F5 (critical, upgrade dead end): a config that targets an MCP-unsupported agent (e.g. pre-split pi) no longer hard-fails setup/status/doctor. The target is dropped with a warning that names the fix (rename pi to omp).

F3 (high): agents/tester.md frontmatter fixed (tools: was a comma-separated string; agnix rejected it, so doctor failed on every fresh install).

F2 (high): prompts announce skipped (no input; answering no) on stdin EOF instead of silently defaulting; git init uses -b main (with fallback for git < 2.28).

F4 (medium): doctor README check passes on config roots without README.md or without the generated block (both optional for users), and the remediation hint is the real command (dotagents sync, not dotagents sync render).

README updated for the new confirm behavior. New tests cover the prune guard (decline / accept / EOF), legacy-config degradation, EOF prompt announcement, and the doctor README pass cases; two existing tests updated to the new contracts. Full suite passes.

Summary by Sourcery

Add safeguards and UX fixes around setup-driven sync, legacy MCP config handling, prompts, doctor README checks, and the tester agent metadata to harden the install funnel and day-one experience.

New Features:

  • Introduce per-harness confirmation for destructive sync actions during setup-driven sync, previewing removals and role overwrites before applying them.

Bug Fixes:

  • Ensure EOF on yes/no and conflict prompts is treated as a skipped response and announced to the user instead of silently defaulting.
  • Allow legacy configs that target MCP-unsupported agents (e.g. pre-split "pi") to degrade with warnings by dropping unsupported targets instead of failing validation.
  • Relax doctor README inventory checks so configs without README.md or without a generated skills block pass, and update the remediation hint to use the main sync command.
  • Fix the tester agent frontmatter so its tools field uses a proper list and other metadata conforms to expected YAML, unblocking doctor on fresh installs.
  • Update setup-driven git init to prefer creating the main branch explicitly, with a fallback for older git versions that do not support -b.

Enhancements:

  • Wire setup-driven sync to use the new destructive action confirmation path and document the behavior change in the README.

Tests:

  • Add tests covering destructive sync confirmation (accept, decline, EOF), legacy MCP target degradation behavior, EOF prompt announcements, and the relaxed doctor README inventory cases.
  • Update existing MCP validation tests to assert dropped "pi" MCP targets instead of hard failures.

@sourcery-ai

sourcery-ai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements a safer, more user-friendly setup-driven sync flow with per-harness destructive change confirmation, degrades legacy MCP configs targeting unsupported agents instead of hard-failing, relaxes README doctor checks, fixes the tester agent frontmatter, and improves prompts and git init behavior, with tests updated and added to cover the new contracts.

File-Level Changes

Change Details Files
Add per-harness destructive sync confirmation for setup-driven syncs and wire it into runSync via a new ConfirmRemovals option.
  • Introduce confirmDestructiveSyncActions to preview removals and agent role overwrites per detected harness and conditionally drop destructive actions while keeping additions and skill updates
  • Add promptYesNoDefaultNo helper that defaults to no on EOF and announces the skipped input
  • Set ConfirmRemovals in runOptions when setup calls runSync so only setup-driven syncs perform the destructive confirmation
  • Add tests covering accept, decline, and EOF behaviors for confirmDestructiveSyncActions and the EOF behavior for promptYesNo
cmd/dotagents/setup_scaffold.go
cmd/dotagents/setup.go
cmd/dotagents/main.go
cmd/dotagents/sync.go
cmd/dotagents/setup_separation_test.go
Change prompts to explicitly announce skips on EOF and refine prompt semantics.
  • Update promptYesNo to print 'skipped (no input; answering no)' when stdin is EOF before returning false
  • Update promptConflict to print 'skipped (no input)' when stdin is EOF before returning 'skip'
  • Add a dedicated test validating that promptYesNo on EOF both returns false and emits the skip announcement
cmd/dotagents/setup_scaffold.go
cmd/dotagents/setup_separation_test.go
Relax doctor README inventory checks to treat missing README or generated block as optional, and fix remediation messaging.
  • Modify checkREADMESkillInventory to pass when README.md is absent, with an explanatory detail message
  • Detect README.md files without the generated skills block markers and treat them as pass with an explanatory detail message
  • Change the remediation string to suggest 'dotagents sync' instead of 'dotagents sync render'
  • Add tests verifying pass behavior for config roots without README.md and for README.md without generated markers, and adjust existing tests to the new remediation message
cmd/dotagents/doctor.go
cmd/dotagents/readme_inventory_test.go
Degrade legacy MCP server configs targeting unsupported agents (notably 'pi') by dropping those targets with a warning instead of failing validation.
  • Refactor MCP server agent validation to build a filtered list of only supported agents
  • For unsupported agents, emit a warning to stderr and skip them instead of returning a validation error
  • Special-case 'pi' to include a hint about renaming it to 'omp' for configs predating the Pi/OMP split
  • Update existing tests to expect non-fatal behavior and that dropped agents are removed from the MCP server targets, and add a new test exercising a mixed legacy config where supported agents are retained
cmd/dotagents/config.go
cmd/dotagents/harness_test.go
cmd/dotagents/setup_separation_test.go
Fix agents/tester.md frontmatter to valid YAML that agnix accepts.
  • Remove unnecessary string quoting from scalar frontmatter fields (name, description, model, effort, color)
  • Change tools from a comma-separated string to a proper YAML list
  • Ensure the overall frontmatter structure is syntactically correct for agnix to parse
agents/tester.md
Improve git init behavior during setup to prefer a main branch and gracefully support older git versions.
  • Update offerGitInit to run 'git init -b main' when initializing the config repo
  • On failure of 'git init -b main', retry with plain 'git init' to support git < 2.28 before surfacing an error
  • Adjust error reporting to include combined output from both attempts when initialization ultimately fails
cmd/dotagents/setup.go
Refresh README documentation for the new destructive sync confirmation behavior during setup.
  • Extend the setup description to explain that before the first sync touches a pre-populated harness, it previews removals/overwrites and asks per harness
  • Document that declining the per-harness prompt keeps that harness's existing files intact
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • In offerGitInit, the fallback git init error path prints err from the first call while using combined output from both calls; this should report err2 (and probably only the second command’s output) to avoid misleading error diagnostics.
  • The new MCP legacy-handling in validateConfig writes warnings directly to os.Stderr; consider routing these through an injected writer or logger so that callers (and tests) can control or capture diagnostics more cleanly.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `offerGitInit`, the fallback `git init` error path prints `err` from the first call while using combined output from both calls; this should report `err2` (and probably only the second command’s output) to avoid misleading error diagnostics.
- The new MCP legacy-handling in `validateConfig` writes warnings directly to `os.Stderr`; consider routing these through an injected writer or logger so that callers (and tests) can control or capture diagnostics more cleanly.

## Individual Comments

### Comment 1
<location path="cmd/dotagents/setup.go" line_range="111-113" />
<code_context>
-	if out, err := exec.Command("git", "-C", repoRoot, "init").CombinedOutput(); err != nil {
-		fmt.Fprintf(streams.out, "git init failed: %v: %s\n", err, strings.TrimSpace(string(out)))
-		return
+	if out, err := exec.Command("git", "-C", repoRoot, "init", "-b", "main").CombinedOutput(); err != nil {
+		// -b needs git >= 2.28; retry without it before giving up.
+		if out2, err2 := exec.Command("git", "-C", repoRoot, "init").CombinedOutput(); err2 != nil {
+			fmt.Fprintf(streams.out, "git init failed: %v: %s\n", err, strings.TrimSpace(string(append(out, out2...))))
+			return
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Error reporting on git init retry uses the first error and concatenated outputs, which can obscure the actual failure.

When the retry `git init` fails, the log still uses `err` from the first attempt and a concatenated `out`/`out2`, so `err2` is never surfaced and the source of the failure is unclear. It would be better to log `err2` and `out2` when the second attempt fails, and optionally note the initial `-b main` failure separately instead of merging the outputs.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread cmd/dotagents/setup.go
Comment on lines +111 to +113
if out, err := exec.Command("git", "-C", repoRoot, "init", "-b", "main").CombinedOutput(); err != nil {
// -b needs git >= 2.28; retry without it before giving up.
if out2, err2 := exec.Command("git", "-C", repoRoot, "init").CombinedOutput(); err2 != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (bug_risk): Error reporting on git init retry uses the first error and concatenated outputs, which can obscure the actual failure.

When the retry git init fails, the log still uses err from the first attempt and a concatenated out/out2, so err2 is never surfaced and the source of the failure is unclear. It would be better to log err2 and out2 when the second attempt fails, and optionally note the initial -b main failure separately instead of merging the outputs.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e006b56af6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cmd/dotagents/config.go
}
kept = append(kept, agentName)
}
cfg.MCPServers[i].Agents = kept

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve MCP scope when dropping unsupported targets

When a legacy config scopes an MCP server only to pi, this assignment leaves Agents as an empty slice after the unsupported target is skipped. desiredMCPServersForAgent treats an empty Agents list as “apply to every MCP-capable harness”, so setup/sync will install that pi-only server into Claude/Codex/OMP instead of ignoring it as the warning says. This can unexpectedly add MCP commands/secrets to unrelated harness configs; unsupported-only targets need to be removed without turning into the global default.

Useful? React with 👍 / 👎.

@yourconscience
yourconscience merged commit 099b94c into main Jul 17, 2026
4 checks passed
@yourconscience
yourconscience deleted the fix/funnel branch July 17, 2026 10:29
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