Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions convex/lib/public.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,32 @@ describe('public skill mapping', () => {
comments: 0,
})
})

it('returns skill when moderationStatus is active', () => {
const skill = makeSkill({ moderationStatus: 'active' })
expect(toPublicSkill(skill)).not.toBeNull()
})

it('filters out skill when moderationStatus is hidden', () => {
const skill = makeSkill({ moderationStatus: 'hidden' })
expect(toPublicSkill(skill)).toBeNull()
})

it('returns skill when moderationStatus is undefined (legacy)', () => {
const skill = makeSkill({ moderationStatus: undefined as unknown as string })
expect(toPublicSkill(skill)).not.toBeNull()
})

it('filters out soft-deleted skills', () => {
const skill = makeSkill({ softDeletedAt: Date.now() })
expect(toPublicSkill(skill)).toBeNull()
})

it('filters out skills with blocked.malware flag', () => {
const skill = makeSkill({
moderationStatus: 'active',
moderationFlags: ['blocked.malware'],
})
expect(toPublicSkill(skill)).toBeNull()
})
})
21 changes: 20 additions & 1 deletion convex/vt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,16 @@ export const scanWithVirusTotal = internalAction({
handler: async (ctx, args) => {
const apiKey = process.env.VT_API_KEY
if (!apiKey) {
console.log('VT_API_KEY not configured, skipping scan')
console.log('VT_API_KEY not configured, skipping scan — activating skill')
// Activate the skill so it appears in search despite no VT scan.
const version = await ctx.runQuery(internal.skills.getVersionByIdInternal, {
versionId: args.versionId,
})
if (version) {
await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
skillId: version.skillId,
})
}
Comment on lines 308 to 322
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same quality gate bypass - check moderationReason before activating

Suggested change
console.log('VT_API_KEY not configured, skipping scan — activating skill')
// Activate the skill so it appears in search despite no VT scan.
const version = await ctx.runQuery(internal.skills.getVersionByIdInternal, {
versionId: args.versionId,
})
if (version) {
await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
skillId: version.skillId,
})
}
console.log('VT_API_KEY not configured, skipping scan — activating skill')
// Activate the skill so it appears in search despite no VT scan.
const version = await ctx.runQuery(internal.skills.getVersionByIdInternal, {
versionId: args.versionId,
})
if (version) {
const skill = await ctx.runQuery(internal.skills.getSkillByIdInternal, {
skillId: version.skillId,
})
if (skill?.moderationReason !== 'quality.low') {
await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
skillId: version.skillId,
})
}
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: convex/vt.ts
Line: 308:317

Comment:
same quality gate bypass - check `moderationReason` before activating

```suggestion
      console.log('VT_API_KEY not configured, skipping scan — activating skill')
      // Activate the skill so it appears in search despite no VT scan.
      const version = await ctx.runQuery(internal.skills.getVersionByIdInternal, {
        versionId: args.versionId,
      })
      if (version) {
        const skill = await ctx.runQuery(internal.skills.getSkillByIdInternal, {
          skillId: version.skillId,
        })
        if (skill?.moderationReason !== 'quality.low') {
          await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
            skillId: version.skillId,
          })
        }
      }
```

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit a8e62e2. Same fix applied — added skill lookup and moderationReason check before activating. This prevents quality gate quarantine bypass in the non-VT-API path.

return
}

Expand Down Expand Up @@ -524,6 +533,11 @@ export const pollPendingScans = internalAction({
versionId,
vtAnalysis: { status: 'stale', checkedAt: Date.now() },
})
// Activate the skill so it appears in search — absence of a VT
// verdict should not permanently hide a published skill.
await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
skillId,
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bypasses quality gate quarantine - skills with moderationReason: 'quality.low' will be activated even though they should remain hidden

check the skill's moderationReason before activating:

Suggested change
// Activate the skill so it appears in search — absence of a VT
// verdict should not permanently hide a published skill.
await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
skillId,
})
// Activate the skill so it appears in search — absence of a VT
// verdict should not permanently hide a published skill.
const skill = await ctx.runQuery(internal.skills.getSkillByIdInternal, { skillId })
if (skill?.moderationReason !== 'quality.low') {
await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
skillId,
})
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: convex/vt.ts
Line: 536:540

Comment:
bypasses quality gate quarantine - skills with `moderationReason: 'quality.low'` will be activated even though they should remain hidden

check the skill's `moderationReason` before activating:

```suggestion
            // Activate the skill so it appears in search — absence of a VT
            // verdict should not permanently hide a published skill.
            const skill = await ctx.runQuery(internal.skills.getSkillByIdInternal, { skillId })
            if (skill?.moderationReason !== 'quality.low') {
              await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
                skillId,
              })
            }
```

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit a8e62e2. Added getSkillByIdInternal lookup and check if (skill?.moderationReason !== "quality.low") before activating the skill. This ensures that skills in quality gate quarantine remain hidden even when VT scan is unavailable.

staled++
}
continue
Expand All @@ -549,6 +563,11 @@ export const pollPendingScans = internalAction({
versionId,
vtAnalysis: { status: 'stale', checkedAt: Date.now() },
})
// Activate the skill so it appears in search — absence of a VT
// verdict should not permanently hide a published skill.
await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
skillId,
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same quality gate bypass issue as above

Suggested change
// Activate the skill so it appears in search — absence of a VT
// verdict should not permanently hide a published skill.
await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
skillId,
})
// Activate the skill so it appears in search — absence of a VT
// verdict should not permanently hide a published skill.
const skill = await ctx.runQuery(internal.skills.getSkillByIdInternal, { skillId })
if (skill?.moderationReason !== 'quality.low') {
await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
skillId,
})
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: convex/vt.ts
Line: 566:570

Comment:
same quality gate bypass issue as above

```suggestion
            // Activate the skill so it appears in search — absence of a VT
            // verdict should not permanently hide a published skill.
            const skill = await ctx.runQuery(internal.skills.getSkillByIdInternal, { skillId })
            if (skill?.moderationReason !== 'quality.low') {
              await ctx.runMutation(internal.skills.setSkillModerationStatusActiveInternal, {
                skillId,
              })
            }
```

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit a8e62e2. Same fix applied here — added skill lookup and moderationReason check before activating. Skills with quality.low moderation reason will not be activated.

staled++
}
continue
Expand Down