Skip to content

fix: gate Kimi Code scanner on its own install marker - #18

Merged
AnobleSCM merged 2 commits into
mainfrom
phantom-kimi-fix-024
Aug 4, 2026
Merged

AnobleSCM merged 2 commits into
mainfrom
phantom-kimi-fix-024

Conversation

@AnobleSCM

@AnobleSCM AnobleSCM commented Aug 3, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Bug: the Kimi Code scanner attributed anything under ~/.agents/skills / <cwd>/.agents/skills to Kimi Code unconditionally, with no check that Kimi Code was actually installed. That directory is the shared global install target skills.sh uses for several non-Kimi tools (Cline, Warp, Zed, Dexto, Loaf) — a user with one of those and no Kimi Code saw a phantom "Kimi Code" section. At user scope it was usually masked by scan-order dedupe (Claude Code's link farm wins); at project scope there was no dedupe to mask it, and the existing test suite already proved the misattribution.
  • Fix: detectKimiCode() in src/manifest/kimi.ts now runs only when its own install marker exists on disk — ~/.kimi-code at user scope, <cwd>/.kimi-code at project scope — checked independently per scope with a pure stat, no file reads. No marker → zero contribution anywhere: no section, no path in the empty-state "Looked in" list, no entry in --json paths_checked. The skill goes undetected rather than misattributed (undercount-honest). Marker present → output is unchanged from 0.2.3.
  • Hardening (post cross-review): the marker check now also requires isDirectory() on that same stat() result — a stray file named .kimi-code no longer opens the gate. A symlink to a real directory still does (stat follows symlinks; unchanged).
  • README's locations table now says "(only when installed — see below)" for Kimi Code, with a new paragraph explaining the gate; the dedupe-order bullet also now says "(Kimi Code: only when installed)" so it stays true in the no-marker state. CHANGELOG entry added. Version bumped to 0.2.4 across package.json, both package-lock.json version fields, and src/version.ts (enforced by the existing version.parity.test.ts).
  • Samples regenerated from a real run (post cross-review): the README's terminal block, its --json block, and assets/devcat-report.svg are all re-captured from one real run of the built 0.2.4 binary against the same 26-tool fixture the 0.2.3 example used. This also caught a pre-existing staleness unrelated to this fix: "locations checked" was already wrong on main (documented as 14; a real run of the published devcat-cli@0.2.3 against a fixture reproducing the exact same tool inventory reports 19 — confirmed against the npm registry tarball). The 0.2.4 regeneration correctly shows 16: same 19, minus the 3 phantom project-scope Kimi paths this fix stops claiming to have checked (this fixture has no project-level .kimi-code). No other number in the example changed.
  • No other scanner touched, no new dependencies, no new flags/commands.

Test plan

  • test/unit/manifest/kimi.marker.test.ts (new, 8 tests) — the gate itself: no marker → zero tools + zero paths at each scope independently; bare marker → normal scan runs; project-only / user-only marker → the other scope stays empty; same fixture with the marker toggled mid-test shows only the gated paths change; a stray file named .kimi-code does not open the gate; a symlink to a real directory does
  • test/integration/kimi-marker-gate.test.ts (new, 6 tests) — full pipeline proof across the terminal report, --markdown, --json, and the empty-state "Looked in" list, for: a skills.sh-only fixture with no marker (empty stack), the same fixture mixed with a real Claude Code tool (no Kimi Code section anywhere), marker present at both scopes (Kimi Code appears, byte-consistent with unconditional scanning), and project-only marker with the user marker absent
  • test/unit/manifest/kimi.test.ts / kimi.skills.test.ts (existing files, 1 new test total) — existing fixtures updated to declare the install marker wherever their intent is "Kimi is genuinely installed" (preserves original coverage/assertions unchanged); added one new inverse test directly next to the original bug-shaped test (~/.agents/skills-only skill, no marker → invisible, not attributed to Kimi Code)
  • 15 new tests total — 8 in kimi.marker.test.ts, 6 in kimi-marker-gate.test.ts, 1 in kimi.skills.test.ts (not 13 across just the two new files, as an earlier version of this description said)
  • npm run lint, npm run build, npm test — all green (321/321 tests, 37 files)
  • npm pack --dry-run file list diffed byte-for-byte against the published devcat-cli@0.2.3 tarball from the npm registry — identical set of 69 files, only content sizes changed where expected (kimi.js, README.md, package.json version)
  • Regenerated samples cross-checked three ways on the real 0.2.4 capture: ANSI-stripped colored output equals the plain capture byte-for-byte (strip-invariant); the SVG's visible text, reassembled from its <tspan>s, equals the plain capture byte-for-byte; and feeding the same generator the real 0.2.3 capture reproduces the currently-committed SVG byte-for-byte except for the one already-known-stale line, which independently confirms the fixture and generator are both faithful

🤖 Generated with Claude Code

~/.agents/skills is not Kimi's own directory — it is the shared install
target skills.sh (vercel-labs) uses for several non-Kimi tools (Cline,
Warp, Zed, Dexto, Loaf). The Kimi Code scanner attributed anything found
there to Kimi Code unconditionally, with no check that Kimi was actually
installed, so a user with one of those tools and no Kimi saw a phantom
"Kimi Code" section. At user scope this was usually masked by scan-order
dedupe (Claude Code's link farm wins); at project scope there was no
dedupe to mask it, and the existing test suite already proved the
misattribution.

detectKimiCode() now runs only when its own install marker exists on
disk — ~/.kimi-code at user scope, <cwd>/.kimi-code at project scope —
checked independently per scope with a pure stat, no file reads. Without
the marker, Kimi Code contributes nothing: no section in any report, no
path in the empty-state "Looked in" list, no entry in --json
paths_checked. With the marker present, output is unchanged from 0.2.3.

Version 0.2.4.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

…, doc claim

Four items from the cross-review verdict:

1. README.md's dedupe-order bullet said a Kimi-Code-only skill "still
   appears under that client" unconditionally — false in the no-marker
   state, which is this release's entire point. Added the qualifier
   ("Kimi Code: only when installed").

2. The README's terminal block, its --json block, and
   assets/devcat-report.svg were regenerated from one real run of the
   built 0.2.4 binary against the same 26-tool fixture the 0.2.3 example
   used (same tool inventory, verified against the fixture reproducing
   the current README byte-for-byte via the real published 0.2.3
   tarball). This also surfaced a pre-existing staleness unrelated to
   this fix: "locations checked" was already wrong on main (documented
   as 14; a real 0.2.3 run reports 19). 0.2.4 correctly shows 16 — the
   same 19 minus the 3 phantom project-scope Kimi paths this fix stops
   claiming to have checked. Nothing else in the example changed.

3. dirExists() now reuses the existing stat() result's isDirectory(),
   so a stray file named .kimi-code no longer opens the gate. No extra
   syscall; a symlink to a real directory still passes (stat follows
   symlinks, unchanged).

4. Corrected the PR body: 15 new tests total (8 in kimi.marker.test.ts,
   6 in kimi-marker-gate.test.ts, 1 in kimi.skills.test.ts), not "13
   across the two new files" as originally stated.

No version bump — still 0.2.4, unpublished.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@AnobleSCM
AnobleSCM marked this pull request as ready for review August 4, 2026 00:22
@AnobleSCM
AnobleSCM merged commit 752bea4 into main Aug 4, 2026
6 checks passed
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@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: d1055d909c

ℹ️ 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 src/manifest/kimi.ts
/** Pure existence check — no file is read, matching this scanner's names-only philosophy. */
async function kimiInstalled(opts: { cwd?: string; scope: 'project' | 'user' }): Promise<boolean> {
if (opts.scope === 'user') return dirExists(join(homedir(), '.kimi-code'));
return opts.cwd != null && (await dirExists(join(opts.cwd, '.kimi-code')));

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 upward discovery when checking the project marker

When DevCat runs from a subdirectory of a Kimi project, this exact-cwd check returns false even if the project root contains .kimi-code/skills. The detector below deliberately uses findUpwardDir() for both Kimi skill roots because Kimi resolves them from the project root, so the early return prevents that existing upward scan and silently omits valid project skills. The project gate should recognize the marker at the same upward-resolved root rather than requiring <cwd>/.kimi-code.

Useful? React with 👍 / 👎.

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