[PR #300] fix: activate skills when VT scan is unavailable or stales out #319

Open
opened 2026-02-15 17:16:53 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/openclaw/clawhub/pull/300
Author: @superlowburn
Created: 2/14/2026
Status: 🔄 Open

Base: mainHead: fix/hidden-skills-after-stale-vt-scan


📝 Commits (1)

  • fb76bdf fix: activate skills when VT scan is unavailable or stales out

📊 Changes

2 files changed (+48 additions, -1 deletions)

View changed files

📝 convex/lib/public.test.ts (+28 -0)
📝 convex/vt.ts (+20 -1)

📄 Description

Summary

Fixes #139 — published skills return success but are not visible in search.

Root cause: insertVersion always sets moderationStatus: 'hidden' on publish (skills.ts:3180). The only path to 'active' is through approveSkillByHashInternal, called when VirusTotal returns a verdict. Three code paths leave the skill permanently hidden with no recovery:

  1. VT_API_KEY not configuredscanWithVirusTotal logs and returns early, skill stays hidden forever
  2. VT hash not found after 10 poll attemptspollPendingScans marks scan as stale but never activates the skill
  3. VT hash found but no Code Insight after 10 attempts — same stale path, same missing activation

Since toPublicSkill() (public.ts:56) filters out any skill where moderationStatus !== 'active', these skills never appear in search results or on the website despite the CLI returning success.

Fix: Call setSkillModerationStatusActiveInternal in all three paths so the skill becomes searchable. If VT later returns a malicious/suspicious verdict, approveSkillByHashInternal will correctly re-hide and flag it — the existing blocked.malware flag check in toPublicSkill (line 57) is unaffected.

  • convex/vt.ts — 3 activation calls added (no-API-key path + 2 stale paths)
  • convex/lib/public.test.ts — 5 new tests documenting moderation filtering behavior

Test plan

  • All 433 existing tests pass (vitest run)
  • New tests cover toPublicSkill moderation filtering: active, hidden, undefined (legacy), soft-deleted, blocked.malware
  • Lint clean (oxlint --type-aware)
  • Verify on staging: publish a skill with VT disabled, confirm it appears in search

🤖 Generated with Claude Code

Greptile Overview

Greptile Summary

This PR fixes a critical issue where published skills would be permanently hidden when VirusTotal scanning fails or times out. The root cause was correctly identified: insertVersion sets moderationStatus: 'hidden' on publish (skills.ts:3180), and without a VT verdict, skills never become searchable.

The fix adds three activation calls to make skills visible when VT scanning is unavailable:

  • When VT_API_KEY is not configured (vt.ts:314)
  • When VT hash is not found after 10 poll attempts (vt.ts:538)
  • When VT hash exists but no Code Insight after 10 attempts (vt.ts:568)

The test additions document the toPublicSkill filtering behavior for various moderation states, which correctly validates that only 'active' skills (or legacy undefined status) appear in search, while hidden, soft-deleted, and malware-blocked skills are filtered out.

Critical issue found: The three new activation calls bypass the quality gate quarantine. Skills with moderationReason: 'quality.low' should remain hidden until manual review (see skills.ts:2335-2344), but setSkillModerationStatusActiveInternal unconditionally sets status to active. Since quality.low skills are included in the pending scan queue (skills.ts:1661), they will be incorrectly activated when VT stales out.

Confidence Score: 2/5

  • This PR addresses a real problem but introduces a quality gate bypass vulnerability
  • The PR correctly identifies and fixes the issue where skills remain permanently hidden when VT scanning fails. However, the fix introduces a critical bug: skills quarantined by the quality gate (moderationReason: 'quality.low') will be incorrectly activated when VT scans time out, bypassing the manual review requirement enforced in approveSkillByHashInternal (skills.ts:2335-2344)
  • Pay close attention to convex/vt.ts - all three activation calls need to check for quality.low quarantine before activating skills

Last reviewed commit: fb76bdf


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/openclaw/clawhub/pull/300 **Author:** [@superlowburn](https://github.com/superlowburn) **Created:** 2/14/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/hidden-skills-after-stale-vt-scan` --- ### 📝 Commits (1) - [`fb76bdf`](https://github.com/openclaw/clawhub/commit/fb76bdfbc474703032713a8de3b7d44a777d8496) fix: activate skills when VT scan is unavailable or stales out ### 📊 Changes **2 files changed** (+48 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `convex/lib/public.test.ts` (+28 -0) 📝 `convex/vt.ts` (+20 -1) </details> ### 📄 Description ## Summary Fixes #139 — published skills return success but are not visible in search. **Root cause:** `insertVersion` always sets `moderationStatus: 'hidden'` on publish (skills.ts:3180). The only path to `'active'` is through `approveSkillByHashInternal`, called when VirusTotal returns a verdict. Three code paths leave the skill permanently hidden with no recovery: 1. **`VT_API_KEY` not configured** — `scanWithVirusTotal` logs and returns early, skill stays hidden forever 2. **VT hash not found after 10 poll attempts** — `pollPendingScans` marks scan as `stale` but never activates the skill 3. **VT hash found but no Code Insight after 10 attempts** — same stale path, same missing activation Since `toPublicSkill()` (public.ts:56) filters out any skill where `moderationStatus !== 'active'`, these skills never appear in search results or on the website despite the CLI returning success. **Fix:** Call `setSkillModerationStatusActiveInternal` in all three paths so the skill becomes searchable. If VT later returns a malicious/suspicious verdict, `approveSkillByHashInternal` will correctly re-hide and flag it — the existing `blocked.malware` flag check in `toPublicSkill` (line 57) is unaffected. - `convex/vt.ts` — 3 activation calls added (no-API-key path + 2 stale paths) - `convex/lib/public.test.ts` — 5 new tests documenting moderation filtering behavior ## Test plan - [x] All 433 existing tests pass (`vitest run`) - [x] New tests cover `toPublicSkill` moderation filtering: active, hidden, undefined (legacy), soft-deleted, blocked.malware - [x] Lint clean (`oxlint --type-aware`) - [ ] Verify on staging: publish a skill with VT disabled, confirm it appears in search 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR fixes a critical issue where published skills would be permanently hidden when VirusTotal scanning fails or times out. The root cause was correctly identified: `insertVersion` sets `moderationStatus: 'hidden'` on publish (skills.ts:3180), and without a VT verdict, skills never become searchable. The fix adds three activation calls to make skills visible when VT scanning is unavailable: - When `VT_API_KEY` is not configured (vt.ts:314) - When VT hash is not found after 10 poll attempts (vt.ts:538) - When VT hash exists but no Code Insight after 10 attempts (vt.ts:568) The test additions document the `toPublicSkill` filtering behavior for various moderation states, which correctly validates that only `'active'` skills (or legacy undefined status) appear in search, while hidden, soft-deleted, and malware-blocked skills are filtered out. **Critical issue found:** The three new activation calls bypass the quality gate quarantine. Skills with `moderationReason: 'quality.low'` should remain `hidden` until manual review (see skills.ts:2335-2344), but `setSkillModerationStatusActiveInternal` unconditionally sets status to active. Since quality.low skills are included in the pending scan queue (skills.ts:1661), they will be incorrectly activated when VT stales out. <h3>Confidence Score: 2/5</h3> - This PR addresses a real problem but introduces a quality gate bypass vulnerability - The PR correctly identifies and fixes the issue where skills remain permanently hidden when VT scanning fails. However, the fix introduces a critical bug: skills quarantined by the quality gate (`moderationReason: 'quality.low'`) will be incorrectly activated when VT scans time out, bypassing the manual review requirement enforced in `approveSkillByHashInternal` (skills.ts:2335-2344) - Pay close attention to convex/vt.ts - all three activation calls need to check for quality.low quarantine before activating skills <sub>Last reviewed commit: fb76bdf</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-15 17:16:53 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: openclaw/clawhub#319