Skip to content

fix(yara): triage skill installs on every harness - #997

Open
gewenyu99 wants to merge 4 commits into
mainfrom
posthog-code/triage-skill-installs-on-every-harness
Open

fix(yara): triage skill installs on every harness#997
gewenyu99 wants to merge 4 commits into
mainfrom
posthog-code/triage-skill-installs-on-every-harness

Conversation

@gewenyu99

Copy link
Copy Markdown
Collaborator

Skill-install scans ran untriaged on 5 of 6 install sites, so YARA terminated on first-party skills — ~15 users/day since 07-24.

scanInstalledSkill defaulted its triage provider to one built from the ANTHROPIC_* env vars, which pi and the orchestrator never set (they auth the gateway programmatically), so the default resolved to undefined and every flagged match was acted on. #977 wired auth into pi's install_skill tool, but the orchestrator pre-installs skills itself at orchestrator-runner.ts:292/:478 and never calls that tool. Now the provider resolves once in bootstrapProgram, rides on BootstrapResult, and takes its model from the harness (haiku on anthropic, luna on pi), dispatched through the pi SDK's completeSimple so transport/effort/trace-headers come from buildGatewayModel instead of a hand-rolled axios POST. temperature: 0 is anthropic-only — the gpt-5 line 400s on it, and warlock's fail-safe turned that failure into true_positive, which is why a failed triage call now logs instead of passing silently.

Verified against wizard-workbench/apps/basic-integration/react-native/react-native-saas over wizard-ci: on stock main, 5 skills blocked (triage skipped (no provider)); with this branch, both paths install all 5 (overruled: 6 · poisoned: 0 · install-failed: 0) — orchestrator on openai/gpt-5.6-luna and linear on claude-haiku-4-5.

Not addressed here: the warlock rules still match PostHog's own doc prose ("disable PostHog"), so every install pays a triage call to overrule them, and skill-install still terminates on any severity while Read/Grep only terminate on critical.


Created with PostHog Code

Skill-install scans built their triage provider from a default that only read
the ANTHROPIC_* env vars, which pi and the orchestrator never set — so 5 of 6
install sites ran untriaged, fail-closed, and terminated on first-party skills
(~15 users/day since 07-24). #977 fixed only pi's `install_skill` tool; the
orchestrator pre-installs skills itself and never calls it.

Resolve the provider once in bootstrapProgram, carry it on BootstrapResult, and
pick its model from the harness — haiku on anthropic, luna on pi. Dispatch
through the pi SDK's completeSimple instead of a hand-rolled axios POST, so
transport, reasoning effort and the gateway trace headers come from
buildGatewayModel rather than being restated. temperature 0 is anthropic-only:
the gpt-5 line 400s on it, which warlock's fail-safe turned into
`true_positive` — a failed triage call now logs instead of passing silently.

Generated-By: PostHog Code
Task-Id: a3f36102-7dc4-47ef-b49d-a05e0e12146b
@gewenyu99
gewenyu99 requested a review from a team as a code owner July 27, 2026 23:34
@github-actions

Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci basic-integration
  • /wizard-ci mcp-analytics
  • /wizard-ci revenue

Test an individual app:

  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
Show more apps
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci revenue/stripe

Results will be posted here when complete.

@gewenyu99

Copy link
Copy Markdown
Collaborator Author

/wizard-ci basic-integration

@wizard-ci-bot

wizard-ci-bot Bot commented Jul 27, 2026

Copy link
Copy Markdown

🧙 Wizard CI Results

Trigger ID: f563c62
Workflow: View run

App Confidence PR YARA
basic-integration/android/Jetchat 3/5 #3137 (logs)
basic-integration/angular/angular-saas 5/5 #3135 (logs)
basic-integration/astro/astro-hybrid-marketing 4/5 #3133 (logs)
basic-integration/astro/astro-ssr-docs 5/5 #3130 (logs)
basic-integration/astro/astro-static-marketing 4/5 #3134 (logs)
basic-integration/astro/astro-view-transitions-marketing 5/5 #3132 (logs)
basic-integration/django/django3-saas 5/5 #3136 (logs)
basic-integration/fastapi/fastapi3-ai-saas 4/5 #3144 (logs)
basic-integration/flask/flask3-social-media 5/5 #3138 (logs)
basic-integration/javascript-node/express-todo 4/5 #3131 (logs)
basic-integration/javascript-node/fastify-blog 4/5 #3140 (logs)
basic-integration/javascript-node/hono-links 4/5 #3139 (logs)
basic-integration/javascript-node/koa-notes 5/5 #3143 (logs)
basic-integration/javascript-node/native-http-contacts 5/5 #3142 (logs)
basic-integration/javascript-web/saas-dashboard 5/5 #3141 (logs)
basic-integration/laravel/laravel12-saas 4/5 #3148 (logs)
basic-integration/next-js/15-app-router-saas 5/5 #3147 (logs)
basic-integration/next-js/15-app-router-todo 4/5 #3145 (logs)
basic-integration/next-js/15-pages-router-saas 5/5 #3149 (logs)
basic-integration/next-js/15-pages-router-todo 4/5 #3146 (logs)
basic-integration/nuxt/movies-nuxt-3-6 4/5 #3151 (logs)
basic-integration/nuxt/movies-nuxt-4 4/5 #3150 (logs)
basic-integration/python/meeting-summarizer 5/5 #3152 (logs)
basic-integration/rails/fizzy 3/5 #3153 (logs)
basic-integration/react-native/expo-react-native-hacker-news 5/5 #3155 (logs)
basic-integration/react-native/react-native-saas 4/5 #3154 (logs)
basic-integration/react-router/react-router-v7-project 4/5 #3156 (logs)
basic-integration/react-router/rrv7-starter 4/5 #3157 (logs)
basic-integration/react-router/saas-template pending
basic-integration/react-router/shopper 4/5 #3164 (logs)
basic-integration/sveltekit/CMSaasStarter 4/5 #3160 (logs)
basic-integration/swift/hackers-ios 5/5 #3165 (logs)
basic-integration/tanstack-router/tanstack-router-code-based-saas 4/5 #3159 (logs)
basic-integration/tanstack-router/tanstack-router-file-based-saas 4/5 #3162 (logs)
basic-integration/tanstack-start/tanstack-start-saas 4/5 #3161 (logs)
basic-integration/vue/movies 5/5 #3163 (logs)

Configuration

Setting Value
Wizard ref posthog-code/triage-skill-installs-on-every-harness
Context Mill ref main
PostHog ref master

Search for trigger ID f563c62 in wizard-workbench PRs.

`isTerminalMatch` ended the session on `action: 'block'` at any severity, so the
medium `prompt_injection_posthog_integration_attack` was fatal wherever it fired.
Block is about refusing the operation — PreToolUse still does — not about ending
the run. Skill installs bypassed the shared verdict entirely and terminated on
ANY post-triage match; both install scanners now resolve `scanVerdict` like every
other surface and keep a non-terminal match's skill instead of deleting it.

Also folds `skillsRoot`/`triage` into a named `SkillInstallOptions` so no call
site passes a bare positional `undefined`.

Generated-By: PostHog Code
Task-Id: a3f36102-7dc4-47ef-b49d-a05e0e12146b
@gewenyu99
gewenyu99 requested a review from sarahxsanders July 28, 2026 00:06
… change

Critical-only termination is only safe if the payloads that matter are actually
critical, and nothing checked that. The smoke test now resolves real scans
through the real policy: six injection classes (instruction override, role
hijack, DAN persona, chat markup, base64-in-comment, poisoned SKILL.md) must
stay terminal, and the three first-party doc strings that blocked ~200 runs must
not. Four whole-skill fixtures run the real install scanner with triage
unavailable, so a poisoned skill is still deleted on severity alone and
first-party prose still installs.

Lives in the smoke script rather than the unit suite because vitest aliases
@posthog/warlock to a manual mock (WASM can't load in the runner), so only this
script sees the real rules — and it gates every build and publish.

Generated-By: PostHog Code
Task-Id: a3f36102-7dc4-47ef-b49d-a05e0e12146b
Triage is a boolean classifier, so it should follow the current 4.5 release
rather than pin a dated snapshot the way dispatchable agent models do. Kept out
of MODEL_CAPABILITIES deliberately: it is not a model the switchboard may route
agent work to, and defaultCaps already resolves it correctly.

Generated-By: PostHog Code
Task-Id: a3f36102-7dc4-47ef-b49d-a05e0e12146b
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