Skip to content

feat(skills): pick task skills with one shared resolver, behind wizard-agent-dag - #1551

Merged
edwinyjlim merged 7 commits into
mainfrom
dag/1-skill-resolver
Nov 13, 2026
Merged

edwinyjlim merged 7 commits into
mainfrom
dag/1-skill-resolver

Conversation

@edwinyjlim

@edwinyjlim edwinyjlim commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds wizard-agent-dag, a boolean flag. With it on, the orchestrator picks each task's skills with resolveSkill in @shared/skill-resolution. With it off or unset, the orchestrator uses its menu lookup, resolveSkillVariantId. Both pick the same skill for every skill family, menu id and framework on the recorded menu.

A run pinned to a context-mill release with --context-mill-version uses the menu lookup, flag on or off.

Stack

The five PRs, in merge order:

PR What it does How it fits in
Menu metadata · PostHog/context-mill#447 Adds a title, description and tags to every skill-menu entry. Ships in a context-mill release. PR 1 reads the tags, and resolves the same without them.
PR 1 · Skill resolver · #1551 (this PR) Adds the wizard-agent-dag flag and the shared skill resolver the orchestrator uses when it is on. Base of the wizard stack, on main. Every later PR hangs its new path off this flag.
PR 2 · Project traits · #1552 Adds the project traits service and hands the orchestrator the traits skills match on. On PR 1. Supplies the resolver's match keys. Nothing reads a trait beyond the framework yet.
PR 3 · Queue from frontmatter · #1553 Queues a flow that has no planner prompt from the graph its prompts' frontmatter declares. On PR 2. No flow lacks a planner until PR 4 bundles one.
PR 4 · Prompts in the wizard · #1554 Bundles each orchestrator flow's prompts in its program. With the flag on, runs read them. Top of the stack, on PR 3. posthog-integration's folder has no planner prompt, so PR 3's queue runs it.

The four wizard PRs merge in that order and ship in one release with wizard-agent-dag off. A run with the flag off or unset behaves as it does on main.

How a pick works

A task prompt names its skills by menu id or by skill family, such as skills: [integration, posthog-best-practices].

flowchart TD
  name["A task names a skill"] --> id{"Is the name<br/>a menu id?"}
  id -- yes --> exact["That skill"]
  id -- no --> family["The skills whose group is the name"]
  family --> disagree["Drop a skill whose match key<br/>disagrees with the run's value"]
  disagree --> nokey["Drop a skill with no framework key"]
  nokey --> rank["Rank by keys that agree,<br/>then the default tag, then menu order"]
  rank --> pick["The first one"]
Loading

A key:value tag on a menu entry is a match key, such as framework:nextjs. It says which projects the skill is written for, and the run supplies its values. A key the run has no value for never disagrees. An entry's framework and default fields count as tags, so a menu published without tags resolves the same.

The run supplies one key here: framework.

What is in the PR

Area Change
Flag wizard-agent-dag joins WIZARD_FLAG_KEYS. isAgentDagEnabled(flags) reads it in the switchboard, and is false for a run pinned to a context-mill release.
Resolver @shared/skill-resolution: resolveSkill(entries, name, matchKeys), pure.
Orchestrator The reference skill, the preflight check and each task's install go through one pick function: resolveSkill with the flag on, resolveSkillVariantId with it off.
Skill menu SkillEntry reads title, description and tags. The menu's buildVersion becomes the context_mill_version tag on every later event.
Terminal event setup wizard finished carries the run's wizard flags, so an outcome can be split by flag variant.
Reference skill A run whose framework reference skill cannot be installed still goes on without it, and now sends orchestrator reference skill unavailable with the skill and the reason.
Fixtures fixtures/context-mill/skill-menu.json, recorded with pnpm record:context-mill-fixtures.

Proof of no change

src/agent/runner/sequence/orchestrator/__tests__/skill-equivalence.test.ts compares the two picks for every name a prompt can use against every framework on the menu, no framework, and an unknown framework.

Menu Names Framework values Comparisons Differences
Recorded menu, published in context-mill 1.65.0 514 74 38,036 0
The same menu with every tags field dropped, the shape a release without menu metadata serves 514 74 38,036 0
Published 1.64.0 menu, which has no tags, through CONTEXT_MILL_MENU 511 74 37,814 0

CONTEXT_MILL_MENU=<path to skill-menu.json> runs the same comparison against any other build.

The menu lookup reads an entry's framework and default fields, and the resolver also reads its tags. The same test fails when an entry's tags and fields disagree, and when the recorded menu carries no tags.

Test plan

  • pnpm typecheck
  • pnpm lint
  • pnpm exec vitest run: 282 files pass
  • The equivalence test on the recorded menu, on the same menu with no tags, and on the published 1.64.0 menu
  • Before this merges: re-record fixtures/context-mill/skill-menu.json from the release that ships feat(menu): describe skills with title, description and tags context-mill#447. The committed menu is a local build of that PR, because the published menu has no tags yet

🤖 Generated with Claude Code

…d-agent-dag

Co-Authored-By: Claude <noreply@anthropic.com>
@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 ai-observability
  • /wizard-ci basic-integration
  • /wizard-ci feature-flags
  • /wizard-ci mcp-analytics
  • /wizard-ci replay-vision
  • /wizard-ci revenue
  • /wizard-ci self-driving
  • /wizard-ci warehouse
  • /wizard-ci warehouse-seeded

Test an individual app:

  • /wizard-ci ai-observability/anthropic
  • /wizard-ci ai-observability/google-adk
  • /wizard-ci ai-observability/groq
Show more apps
  • /wizard-ci ai-observability/manual-capture
  • /wizard-ci ai-observability/openai
  • /wizard-ci ai-observability/openai-agents
  • /wizard-ci ai-observability/opentelemetry
  • /wizard-ci ai-observability/vercel-ai
  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/flutter
  • /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 feature-flags/django
  • /wizard-ci feature-flags/next-js
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/go-sdk
  • /wizard-ci mcp-analytics/python-sdk
  • /wizard-ci mcp-analytics/ruby-sdk
  • /wizard-ci mcp-analytics/rust-sdk
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci replay-vision/javascript-node
  • /wizard-ci replay-vision/next-js
  • /wizard-ci replay-vision/react-vite
  • /wizard-ci revenue/stripe
  • /wizard-ci self-driving/astro
  • /wizard-ci self-driving/fastapi
  • /wizard-ci self-driving/nuxt
  • /wizard-ci self-driving/react-router
  • /wizard-ci self-driving/sveltekit
  • /wizard-ci warehouse/monorepo-env
  • /wizard-ci warehouse/multi-source-next
  • /wizard-ci warehouse/stripe-node
  • /wizard-ci warehouse/zero-source
  • /wizard-ci warehouse-seeded/next-stripe
  • /wizard-ci warehouse-seeded/next-stripe-declined

Test against a Context Mill branch:

  • /wizard-ci all context-mill:my-branch

Add context-mill:<branch> to any command above to pin the Context Mill branch. It defaults to main.

Results will be posted here when complete.

@veria-ai

veria-ai Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

PR overview

No security issues were found in this pull request.

Reviews

@posthog-security-review-bot posthog-security-review-bot Bot added security-review Request a security review and removed security-review Request a security review labels Nov 12, 2026
@posthog-security-review-bot

posthog-security-review-bot Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

✅ Security review complete — 3271da60c96a

No findings above the confidence threshold, in 5 min.

Add the security-review label to run again on the latest commit.

@posthog-security-review-bot

posthog-security-review-bot Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

✅ Security review complete — 3271da60c96a

No findings above the confidence threshold, in 4 min.

Add the security-review label to run again on the latest commit.

@johncwaters johncwaters left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note

Automated review. Not written by a human.

Verdict: APPROVE WITH NITS

See inline comments.

Comment thread scripts/README.md Resolved

@sarahxsanders sarahxsanders left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not seeing any major blockers in any of these PRs, so I am gonna leave general comments

centralizing skill selection makes sense to me + the existing path behind the flag makes things a little less scary :)

@posthog-security-review-bot posthog-security-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Agent-driven security review - no findings.

@posthog-security-review-bot posthog-security-review-bot Bot removed the security-review Request a security review label Nov 12, 2026

@posthog-security-review-bot posthog-security-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Agent-driven security review - no findings.

The equivalence test also runs on the recorded menu with every tags field
dropped, the shape a context-mill release without menu metadata serves.

Co-Authored-By: Claude <noreply@anthropic.com>

@gewenyu99 gewenyu99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Initial comments, these generally loook pretty clean. Gonna spend some more time trying to break it with. claude.

Comment thread src/shared/README.md Resolved
Comment thread src/shared/skill-resolution.ts Resolved
if (resolveSkillVariantId(menuSkillEntries, skillId, framework)) {
continue;
}
if (pickSkillId(skillId)) continue;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not from this PR, but this check now decides more. When a skill name is gone from the menu, the user is told the instructions "failed to download" and to try again. Retrying can't help.

That's what an older flag-on wizard hits after context-mill renames a skill. The message should say the skill is missing from the menu and to update the wizard.

edwinyjlim and others added 3 commits November 12, 2026 19:32
A tag whose key names a built-in object property, such as constructor:x,
made the resolver read that property and throw. It now reads only keys
the run supplies.

The shared README says a run with no framework resolves no family. The
fixture recorder reads the menu before it writes, so a response that is
not a menu leaves the fixture alone.

Co-Authored-By: Claude <noreply@anthropic.com>
…able

A run whose framework reference skill cannot be installed goes on without
the example and the framework rules. It now sends
orchestrator reference skill unavailable with the skill and the reason.

Co-Authored-By: Claude <noreply@anthropic.com>
edwinyjlim and others added 2 commits November 13, 2026 11:33
The release carries the menu's titles, descriptions and tags, so the
recorded menu is now a published one.

Co-Authored-By: Claude <noreply@anthropic.com>
@edwinyjlim
edwinyjlim merged commit 126ded2 into main Nov 13, 2026
20 checks passed
@edwinyjlim
edwinyjlim deleted the dag/1-skill-resolver branch November 13, 2026 19:58
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.

4 participants