Skip to content

fix: Windows CRLF + MCP/CLI coexistence (doctor false-positives)#1190

Open
geormic12 wants to merge 2 commits into
garrytan:masterfrom
geormic12:fix/check-resolvable-crlf-windows
Open

fix: Windows CRLF + MCP/CLI coexistence (doctor false-positives)#1190
geormic12 wants to merge 2 commits into
garrytan:masterfrom
geormic12:fix/check-resolvable-crlf-windows

Conversation

@geormic12
Copy link
Copy Markdown

Summary

Two related fixes for Windows users running gbrain alongside an attached MCP server (the common Claude Code configuration):

  1. check-resolvable.tsextractTriggers regex didn't tolerate CRLF line endings, so every Windows-edited skill got flagged as mece_gap even when triggers were present. One-character fix (\n\r?\n).

  2. doctor.ts + cli.tsgbrain doctor reports connection [warn]: Could not connect to configured DB every time it runs while gbrain serve MCP holds the PGLite single-writer lock. Co-existence with MCP is expected, not an error. Patch detects the lockfile (postmaster.pid) and demotes to connection [ok]: info: DB owned by another process ..., pointing the user at mcp__gbrain__get_health for DB-backed checks.

Repro

On a clean Windows clone with an attached gbrain serve MCP:

```
$ gbrain doctor --strict --json
status: warnings
health_score: 90
resolver_health [warn]: 39 issue(s): 0 error(s), 39 warning(s)
(all 39 are mece_gap on upstream skills whose triggers: arrays ARE in
the frontmatter but get missed because of CRLF line endings)
skill_conformance [ok]: 46/46 skills pass
connection [warn]: Could not connect to configured DB ...
```

After both fixes:

```
$ gbrain doctor --strict --json
status: healthy
health_score: 100
resolver_health [ok]: 46 skills, all reachable
skill_conformance [ok]: 46/46 skills pass
connection [ok]: info: DB owned by another process (likely 'gbrain serve' MCP holding the PGLite single-writer lock). Filesystem checks ran; use 'mcp__gbrain__get_health' for DB-backed checks.
```

Why two commits

Each commit is independently revertable. Commit 1 is a one-character regex fix. Commit 2 extends runDoctor's signature with an optional opts parameter (backward-compatible — only the catch-path caller passes it).

Test plan

  • gbrain doctor --strict on Windows with attached MCP — clean output
  • gbrain doctor --strict on Windows without MCP — connection check behaves as before
  • Linux/macOS no-regression — LF files already worked; please verify
  • CI passes

Context

Surfaced during a framework rewrite that's installing gbrain as the canonical knowledge layer on Windows. Documented in the issue at https://github.com/garrytan/gbrain/issues — happy to link if you'd like a separate report.

🤖 Generated with Claude Code

geormic12 and others added 2 commits May 18, 2026 22:28
`extractTriggers` used `/^---\n([\s\S]*?)\n---/` to capture the YAML
frontmatter block before scanning for a `triggers:` array. The literal `\n`
bytes don't match CRLF line endings, so on Windows the frontmatter match
failed before triggers were ever inspected, and every Windows-edited skill
got flagged as a `mece_gap` warning ("Skill 'X' has no triggers: field in
its SKILL.md frontmatter") even when the triggers were present.

Repro on a clean Windows clone: doctor --strict --json against a fresh
brain reported 39 of 42 skills as mece_gap warnings (every upstream skill
shipped with CRLF endings; only skills authored on the same machine via
gbrain skillify scaffold had LF endings and passed). After the fix:
0 mece_gap warnings, all 46 skills pass conformance, health_score 90 -> 100.

The single-character fix adds `\r?` before each `\n` in the outer match;
the inner triggers regex already tolerates `\r` because `\s` includes it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When `gbrain serve` is attached as an MCP server (the common Claude Code
configuration), PGLite's single-writer lock blocks `gbrain doctor` from
opening its own DB connection. The catch path at cli.ts surfaced this as
`connection [warn]: Could not connect to configured DB ...`, which is
noisy: co-existence with an attached MCP is expected behavior, the user
has DB-backed health available via `mcp__gbrain__get_health`, and the
warning fires on every CLI invocation while MCP is up.

Patch: in cli.ts, detect the lockfile (postmaster.pid in brain.pglite)
before calling runDoctor, pass an opts.lockHeldByMcp hint. In doctor.ts,
extend runDoctor's signature with the optional opts and demote the
connection check to status 'ok' with an info-prefixed message pointing
the user at the MCP-side health surface. The status type union stays
unchanged ('ok' | 'warn' | 'fail'); the info-prefix convention is already
used elsewhere in this file (see slug_fallback_audit).

Result: doctor --strict against a brain whose MCP is attached now reports
status 'healthy', score 100, instead of status 'warnings', score 95.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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