Skip to content

fix(sync): no false warnings outside a project; stop the Codex claude-flow re-import loop - #233

Merged
pacphi merged 1 commit into
mainfrom
fix/sync-user-scope-false-warnings
Sep 23, 2026
Merged

pacphi merged 1 commit into
mainfrom
fix/sync-user-scope-false-warnings

Conversation

@pacphi

@pacphi pacphi commented Sep 23, 2026

Copy link
Copy Markdown
Owner

Problem

ak sync run from ~/.claude (not a git repository) ended with a hard failure, plus warnings that weren't true:

Output line Verdict Cause
✗ AQE embedding projections: … missing registrations false error Treated the current folder as a project and required ~/.claude/.mcp.json to register AQE. An earlier sync had also written a stray ~/.claude/.claude/settings.local.json.
⚠ statusline: no statusline.cjs false warning No ruflo helpers exist there, so there is nothing to patch.
⚠ statusline: helper stamp still stale after heal false claim A missing stamp counted as "stale", but ruflo never refreshes a folder without hook-handler.cjs.
✓ ruflo helpers: signed generated helpers refreshed false claim Any clean exit counted as a refresh; ruflo returned refreshed: false.
Codex repair of [mcp_servers.claude-flow] real, but never stayed fixed Codex's Claude config import re-adds it (see below).

The Codex loop

Codex keeps a log of its Claude imports (~/.codex/state_5.sqlite, table external_agent_config_imports). It shows the import re-running about every 12 hours and adding Claude's user-scope claude-flow back each time. The repair had run 14 times between 2026-09-04 and 2026-09-23.

In Codex's source (rust-v0.156.1, external-agent-migration/src/config_values.rs merge_missing_mcp_servers), a server is imported only when Codex has no server with that name. Codex has no setting to turn the import off. The schedule most likely comes from the closed-source desktop app; that part is inferred.

Fix

Project scope

  • The AQE embedding projection uses paths.repoRoot, the same project gate every other project writer uses.
    • Outside a repository, only the user Codex target applies. Values an earlier version wrote there are removed using its receipt.
    • .mcp.json must register AQE only in a project where AQE has been set up (.agentic-qe/ present).
  • helperStampStale follows ruflo's own precondition: without hook-handler.cjs, a folder is not stale. Ruflo's test "is a safe no-op outside a ruflo project" shows the same behavior.
  • New runHelperRefresh returns refreshed, current or failed based on what ruflo actually did (either the project result or the global result). refreshRufloHelpers keeps its boolean contract.
  • A location with no ruflo helpers gets an info line instead of a warning. Helpers and statusline resolve at the repository root, so running from a subdirectory also works.

Codex

  • The legacy alias is disabled in place instead of deleted. The edit is bounded to that table, backed up, and re-checked afterwards. Codex 0.156.1 accepts the placeholder and codex mcp list shows it as disabled. The name stays taken, nothing launches, and the placeholder is never itself a repair target:
    [mcp_servers.claude-flow]
    # agentic-kit: disabled placeholder — stops Codex's Claude import from
    # re-adding a duplicate of [mcp_servers.ruflo]. Delete this table to undo.
    command = "ruflo"
    args = ["mcp", "start"]
    enabled = false
  • Removing a table now also removes its own child tables. Before, it left an orphaned [mcp_servers.<name>.env].
  • The repair plan and trust manifest now say "disable" instead of "remove".

Docs: ADR-0033 and ADR-0055 (Updated notes), docs/SETUP.md, docs/UPGRADING.md.

Verification

  • pnpm run check: exit 0. Tests: 4320 pass, 0 fail, 6 skipped. Lint: 0 errors; the warnings are the same as on main (71).
  • New regression tests, which fail on main and pass here:
    • outside a repository, no project file is written;
    • a stray owned value is removed by its receipt;
    • .mcp.json must register AQE only in an AQE-initialized repo;
    • a subdirectory resolves to the repository root;
    • "no helpers" is not stale;
    • refresh outcomes are reported separately;
    • "absent statusline" is not flagged as a defect;
    • the placeholder replaces the child env table and is left alone once converged.
  • Existing tests updated: they had asserted codex mcp remove claude-flow calls and now assert the disabled placeholder.
  • Read-only run of this branch from ~/.claude, the repository root and src/lib on the affected machine:
    • The projection passes in all three. From ~/.claude it plans only the stray-value cleanup.
    • From ~/.claude, the statusline is marked absent (info line) and not stale.
    • The Codex repair plan is empty in all three.

🤖 Generated with Claude Code

…-flow re-import loop

`ak sync` run from a non-project folder (e.g. ~/.claude) reported a hard
failure and warnings that were not true, and every sync repeated a Codex
repair that never stayed fixed.

Project scope:
- The AQE embedding projection now uses the enclosing git repository root,
  the same project gate as every other project writer. Outside a repository
  only the user Codex target applies; values an earlier version wrote there
  are relinquished by receipt. The .mcp.json AQE registration is required
  only in an AQE-initialized project (.agentic-qe/ present).
- helperStampStale follows ruflo's own precondition: no hook-handler.cjs
  means ruflo never refreshes that folder, so it is not stale.
- runHelperRefresh reports refreshed/current/failed from ruflo's actual
  result; a no-op no longer prints "helpers refreshed".
- A location with no ruflo helpers gets an info line, not a statusline
  warning. Helpers and statusline resolve at the repository root.

Codex:
- Codex's Claude config import (re-run on a schedule, most likely by the
  desktop app) adds any Claude MCP server whose name Codex lacks, so the
  deleted legacy [mcp_servers.claude-flow] came back within hours (14
  repairs 2026-09-04 → 2026-09-23). The alias is now replaced in place by a
  disabled placeholder (enabled = false), with backup and verification.
  The name stays taken, nothing launches, and the placeholder is never a
  repair target.
- Removing a table now also removes its own child tables, instead of
  leaving an orphaned [mcp_servers.<name>.env].

Docs: ADR-0033, ADR-0055, SETUP.md, UPGRADING.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pacphi
pacphi merged commit 421f4b4 into main Sep 23, 2026
16 checks passed
@pacphi
pacphi deleted the fix/sync-user-scope-false-warnings branch September 23, 2026 16:08
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