Skip to content

fix: clarify skill/soul stats semantics#1233

Open
linfangw wants to merge 6 commits intoopenclaw:mainfrom
linfangw:main
Open

fix: clarify skill/soul stats semantics#1233
linfangw wants to merge 6 commits intoopenclaw:mainfrom
linfangw:main

Conversation

@linfangw
Copy link
Copy Markdown
Contributor

This PR improves stats readability in skill-related UI.

Why

  • Skill detail stats previously mixed icon semantics and number meanings, which made downloads, stars, and installs harder to interpret quickly.
  • Installs context (all-time vs current) needed a cleaner presentation without overloading the primary stat line.

What changed

  • Skill detail stats clarity (src/components/SkillHeader.tsx)

    • Replaced ambiguous icon usage with explicit icons:
      • Download for downloads
      • Users for installs
    • Reordered display to improve scan order: downloads → stars → installs.
    • Simplified installs display to primary all-time installs label.
    • Added hover tooltip exposing both metrics (all-time + current) to preserve detail without UI clutter.
  • List/card metric consistency

    • Updated src/components/SkillStats.tsx and src/components/SoulStats.tsx to use Download icon consistently.
    • Unified star rendering style () and normalized metric order across list/table contexts.
  • Installs tooltip utility + tests

    • Added src/lib/installsTooltip.ts to centralize tooltip text formatting.
    • Added src/lib/installsTooltip.test.ts covering:
      • normal values
      • compact formatting for large numbers
      • zero/current edge cases
      • equal all-time/current values

Impact

  • UX: clearer metric semantics and lower cognitive load on skill pages.
  • Maintainability: installs explanation logic is centralized and test-covered.

Validation

  • Unit tests passed for tooltip/format logic.
  • Relevant skill detail and list page tests passed.
  • Manual dev verification confirms corrected icon semantics and metric ordering.

Problem:
Skills using legitimate API integrations (process.env + fetch) were
permanently flagged as malicious due to CREDENTIAL_HARVEST being
classified as a malicious-level reason code. Once flagged, skills could
not recover to normal status even after clean VT and OpenClaw scans,
because:
1. syncModerationReasons used a partial-update path that only patched
   moderationReason without reconciling moderationFlags, moderationStatus,
   or moderationVerdict.
2. Static scan "you are now a/an" regex over-matched common skill
   preambles, adding spurious INJECTION_INSTRUCTIONS flags.
3. No mechanism existed for external scanner results (VT/LLM) to
   override static suspicious findings when both independently
   confirmed the skill as safe.

Solution:
- Downgrade CREDENTIAL_HARVEST from malicious.env_harvesting to
  suspicious.env_credential_access — env+network is suspicious, not
  malicious, for API integration skills (moderationReasonCodes.ts).
- Remove "you are now a/an" regex from markdown scanning to stop
  false INJECTION_INSTRUCTIONS flags (moderationEngine.ts).
- Add external scanner override in buildModerationSnapshot: when both
  VT and LLM report clean/benign, demote suspicious.* static codes
  from verdict calculation while preserving malicious.* codes and
  keeping all findings in evidence for transparency (moderationEngine.ts).
- Route syncModerationReasons through approveSkillByHashInternal for
  rows with sha256hash, ensuring full moderation state reconciliation.
  For legacy no-hash rows: malicious → escalateSkillByIdInternal
  (immediate hide); clean/suspicious → updateSkillModerationReasonInternal
  (partial fix, matches pre-existing behavior) (vt.ts, skills.ts).
- Add escalateSkillByIdInternal mutation for atomic emergency
  escalation by skillId (sets moderationReason, moderationFlags,
  moderationStatus, hiddenAt, isSuspicious) (skills.ts).
- Ensure approveSkillByHashInternal explicitly hides malicious skills
  by setting moderationStatus to 'hidden' (skills.ts).
- Bump MODERATION_ENGINE_VERSION to v2.1.0.

Frontend:
- Add StaticAnalysisDetail component to display static scan findings
  with severity-aware styling (SkillSecurityScanResults.tsx).
- getStaticGuidance now accepts vtStatus/llmStatus and shows "Confirmed
  safe by external scanners" (benign/green) when both are clean, instead
  of always showing yellow "Patterns worth reviewing" for critical
  severity findings.
- Render SecurityScanResults and disclaimer when only static findings
  are present (SkillHeader.tsx).

Testing:
- 7 new unit tests in moderationEngine.test.ts covering:
  - CREDENTIAL_HARVEST downgrade (suspicious, not malicious)
  - "you are now" no longer flagged in markdown
  - "ignore previous instructions" still flagged
  - buildModerationSnapshot: VT+LLM clean demotes suspicious codes
  - buildModerationSnapshot: malicious codes preserved despite clean VT+LLM
  - Single-scanner-clean does not demote suspicious codes
  - VT suspicious + LLM clean does not demote suspicious codes
- All existing tests pass with engine version bump to v2.1.0.

Follow-up needed (not in this commit):
- One-time backfill for already-misflagged skills (cursor-based,
  re-run approveSkillByHashInternal on isSuspicious=true + clean VT).

Made-with: Cursor
Reconcile conflicting moderation engine, VT sync, skill moderation, and scan UI changes so the branch keeps the newer package and security behavior without conflict markers.

Made-with: Cursor
Improve skill/soul stats readability by using download/user icons, reordering metrics for clearer scanning, and adding installs tooltip text coverage tests. Also remove a duplicate Convex internal mutation export that broke schema bundling.

Made-with: Cursor
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 24, 2026

@linfangw is attempting to deploy a commit to the 0xBuns Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 24, 2026

Greptile Summary

This PR improves the clarity of skill/soul metric displays by swapping the generic Package icon for explicit Download and Users icons, reordering stats to downloads → stars → installs, and extracting a tested installsTooltip utility that exposes both all-time and current install counts on hover — reducing visual clutter while keeping the detail accessible.

  • UI changes (SkillHeader.tsx, SkillStats.tsx, SoulStats.tsx) are clean and consistent; icon semantics, order, and star rendering are all correctly normalised across components.
  • installsTooltip.ts correctly delegates to formatCompactStat for both values; the companion test covers normal, compact, zero, and equal-value cases.
  • convex/skills.ts contains only indentation reformats across ~250 lines, completely unrelated to the PR's stated scope. This adds considerable diff noise and conflicts with the AGENTS.md guideline to keep changes scoped. Consider reverting this file or splitting the formatting into a separate commit.

Confidence Score: 4/5

  • Safe to merge; the functional changes are correct and well-tested — the only concern is unrelated formatting churn in convex/skills.ts.
  • All logic changes (icon updates, stat ordering, tooltip utility) are correct and covered by tests. The one non-blocking issue is the large set of indentation-only diffs in convex/skills.ts that are unrelated to this PR's scope per AGENTS.md guidelines. No functional regressions were found.
  • convex/skills.ts — contains only formatting churn unrelated to the PR; worth reverting or splitting out to keep the diff clean.

Comments Outside Diff (1)

  1. convex/skills.ts, line 417-444 (link)

    P2 Unrelated formatting changes across this file

    This file has dozens of indentation-only reformats (collapsing object literals from 4-space-offset style to 2-space-offset style) spread across ~250 lines, none of which are related to the stated PR goal of clarifying skill/soul stats semantics. AGENTS.md says: "Keep changes scoped; avoid repo-wide search/replace."

    These formatting-only diffs add significant diff noise and make it harder to audit the real changes. It would be cleaner to either:

    • Revert convex/skills.ts entirely (no logic was changed), or
    • Split them into a separate chore: format commit/PR.

    Context Used: AGENTS.md (source)

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: convex/skills.ts
    Line: 417-444
    
    Comment:
    **Unrelated formatting changes across this file**
    
    This file has dozens of indentation-only reformats (collapsing object literals from 4-space-offset style to 2-space-offset style) spread across ~250 lines, none of which are related to the stated PR goal of clarifying skill/soul stats semantics. `AGENTS.md` says: *"Keep changes scoped; avoid repo-wide search/replace."*
    
    These formatting-only diffs add significant diff noise and make it harder to audit the real changes. It would be cleaner to either:
    - Revert `convex/skills.ts` entirely (no logic was changed), or
    - Split them into a separate `chore: format` commit/PR.
    
    **Context Used:** AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=a1d58d20-b4dd-4cbb-973a-9fd7824e1921))
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: convex/skills.ts
Line: 417-444

Comment:
**Unrelated formatting changes across this file**

This file has dozens of indentation-only reformats (collapsing object literals from 4-space-offset style to 2-space-offset style) spread across ~250 lines, none of which are related to the stated PR goal of clarifying skill/soul stats semantics. `AGENTS.md` says: *"Keep changes scoped; avoid repo-wide search/replace."*

These formatting-only diffs add significant diff noise and make it harder to audit the real changes. It would be cleaner to either:
- Revert `convex/skills.ts` entirely (no logic was changed), or
- Split them into a separate `chore: format` commit/PR.

**Context Used:** AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=a1d58d20-b4dd-4cbb-973a-9fd7824e1921))

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "update" | Re-trigger Greptile

Copy link
Copy Markdown

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

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: 028191f204

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/components/SkillHeader.tsx Outdated
Copy link
Copy Markdown

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

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: 01a78208a7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/components/SkillHeader.tsx Outdated
Show installs in the skill header when either installs metric is positive, and fall back to current installs when all-time installs are still zero for legacy or partially backfilled rows.

Made-with: Cursor
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