fix: clarify skill/soul stats semantics#1233
Conversation
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
|
@linfangw is attempting to deploy a commit to the 0xBuns Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryThis PR improves the clarity of skill/soul metric displays by swapping the generic
Confidence Score: 4/5
|
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
💡 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".
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
This PR improves stats readability in skill-related UI.
Why
downloads,stars, andinstallsharder to interpret quickly.all-timevscurrent) needed a cleaner presentation without overloading the primary stat line.What changed
Skill detail stats clarity (
src/components/SkillHeader.tsx)Downloadfor downloadsUsersfor installsdownloads → stars → installs.all-time installslabel.all-time+current) to preserve detail without UI clutter.List/card metric consistency
src/components/SkillStats.tsxandsrc/components/SoulStats.tsxto useDownloadicon consistently.⭐) and normalized metric order across list/table contexts.Installs tooltip utility + tests
src/lib/installsTooltip.tsto centralize tooltip text formatting.src/lib/installsTooltip.test.tscovering:Impact
Validation