Skip to content

feat(orchestrator): queue a flow with no planner prompt from its frontmatter - #1553

Merged
edwinyjlim merged 11 commits into
dag/2-project-traitsfrom
dag/3-queue-from-frontmatter
Nov 13, 2026
Merged

edwinyjlim merged 11 commits into
dag/2-project-traitsfrom
dag/3-queue-from-frontmatter

Conversation

@edwinyjlim

@edwinyjlim edwinyjlim commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Summary

A flow's prompts already declare its task graph: each task's dependsOn names the task types it runs after, and one task is the sink. With wizard-agent-dag on, a flow that has no seed: true planner prompt is queued from that graph, and no planner agent runs.

Every flow context-mill serves has a planner prompt, so no run takes this path until PR 4 bundles posthog-integration's prompts without one. PR 4 also narrows the path to flows the wizard bundles.

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 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 (this PR) 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 run gets its queue

flowchart TD
  load["Load the flow's prompts"] --> seed{"A seed: true prompt?"}
  seed -- yes --> planner["Run the planner agent,<br/>which calls enqueue_task per task"]
  seed -- "no, flag on" --> graph["Read the graph from frontmatter"]
  seed -- "no, flag off" --> err["Fail: no seed agent prompt"]
  graph --> drop["Drop the tasks the run excludes,<br/>and give their dependencies<br/>to the tasks that waited on them"]
  drop --> guards["Queue each task through<br/>the enqueue_task guards"]
  planner --> queue["Queue"]
  guards --> queue
  queue --> drain["Drain: one agent per task"]
Loading

src/agent/runner/sequence/orchestrator/task-graph.ts has two functions:

Function What it does
planTaskGraph(graph, keep) Orders the tasks keep allows, each after every task it waits for and the sinks last. A dropped task hands its dependencies to the tasks that waited on it. Throws a TaskGraphError when the tasks cannot be ordered.
queueTaskGraph(ctx, graph) Queues the plan with applyEnqueue, so each task passes the guards an agent's enqueue_task passes. A sink also waits for every queued task its dependencies do not reach, such as a task the wizard queued first. Logs each dependsOn name the flow does not declare, once. Throws a TaskGraphError when a guard rejects a task.

Which tasks a run leaves out stays where it is: the program's excludedTaskTypes for flags and CI, and seedTasks for tasks the wizard queues itself. The registry exposes the declared graph, excluded tasks included, as registry.graph.

orchestrator seeded carries which one queued the run as source, planner or frontmatter, on every run with the flag on or off. It is the one thing a flag-off run sends that it did not send before.

When the graph cannot be queued

Case Error code What the run does
The tasks cannot be ordered, or a queue guard rejects one PHW_AGENT_ORCHESTRATOR_TASK_GRAPH Fails before any task runs, with a message for the user. Sends orchestrator task graph rejected with the reason: unorderable, or the guard's name.
The run excludes every task, so nothing is queued PHW_AGENT_ORCHESTRATOR_HOLLOW_RUN Fails and says the setup had no steps to run. A run with a planner keeps the planning-step message.

posthog-integration's graph

The graph the recorded integration-v2 prompts declare. Edges a longer path already implies are left out.

flowchart LR
  install --> identify
  init --> identify
  install --> et["error-tracking"]
  init --> et
  identify --> capture
  identify --> mcp["mcp-analytics"]
  capture --> aio["ai-observability"]
  aio --> logs
  capture --> dashboard
  mcp --> dashboard
  et --> review
  mcp --> review
  logs --> review
  dashboard --> report
  review --> report
  warehouse -.-> report
Loading

mcp-analytics, ai-observability and logs are optional and leave a run when the program excludes them. warehouse is queued by the wizard from what detection found, and only report waits for it.

Proof: the graph queues what the planner queues

The planner's own choices are which tasks to queue. Thirty days of orchestrator seeded events show what it chose.

Task set the planner queued Share of runs The graph queues it when
The ten default tasks and warehouse 60.1% Sources were detected
The ten default tasks 38.3% Nothing is excluded but mcp-analytics
With mcp-analytics 1.0% Its flag is on and the project has an MCP server
With mcp-analytics and warehouse 0.2% Both
Without ai-observability and logs 0.1% Their flag is off
Without them, with warehouse Under 0.1% Both
Anything else 0.2% Never

The last row is planner slips: a task queued twice, a plan that stopped after install and init, or a plan with no report. The graph cannot produce them.

src/agent/runner/sequence/orchestrator/__tests__/recorded-flow-graphs.test.ts pins the task sets and the edges, and checks every recorded flow: each dependsOn names a task in its folder, the folder has one sink and can be ordered, and each skills entry is on the recorded menu.

Fixtures

fixtures/context-mill/ holds context-mill 1.65.0's agent menu and its 49 prompts, one folder per flow, in their own commit. pnpm record:context-mill-fixtures records them. The recorder accepts a flow or id only as one path segment and checks every destination first, so a menu cannot name a file outside the fixtures folder.

Test plan

  • pnpm typecheck
  • pnpm lint
  • pnpm exec vitest run: 286 files pass
  • task-graph.test.ts: the order, dropped tasks, cycles, the sink, a task the wizard queued first, an undeclared dependsOn name logged once, a guard rejection
  • frontmatter-queue.test.ts: a full orchestrator run with no planner, with an excluded task, with a warehouse task the wizard queued first, with a graph that cannot be ordered, with every task excluded, with a planner prompt, and with the flag off
  • The recorded prompts equal the published 1.65.0 release byte for byte

🤖 Generated with Claude Code

edwinyjlim and others added 2 commits November 11, 2026 15:23
The recorder writes the agent menu and every prompt it lists beside the
skill menu, one folder per flow. The graph checks read them.

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

A flow's prompts already declare its graph: each task's dependsOn names
the types it runs after, and one task is the sink. With wizard-agent-dag
on, a flow that has no seed prompt is queued from that graph and no
planner runs. A task the run excludes hands its dependencies to the tasks
that waited on it, and the sink also waits for every task its
dependencies do not reach, the wizard's own tasks among them. Every
enqueue passes the guards enqueue_task passes.

Every flow context-mill serves has a seed prompt, so no run takes this
path yet. orchestrator seeded says which one queued the run, as source.

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

All previously flagged issues have been addressed. No open security concerns remain on this pull request.

Fixed/addressed: 1 · PR risk: 0/10

Reviews

@posthog-security-review-bot posthog-security-review-bot Bot added 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 — 4d12e654199d

1 finding posted as a review (changes requested), in 8 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 — 4d12e654199d

1 finding posted as a review, in 7 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.

analytics.wizardCapture('orchestrator seeded', {
task_count: store.list().length,
types: store.list().map((t) => t.type),
source: seedPrompt ? 'planner' : 'frontmatter',

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.

[convergent: code + redteam + boundary] MEDIUM

Is source on orchestrator seeded meant to ship to flag-off runs too? It isn't gated on isAgentDagEnabled, so every flag-off run (every served flow today) now sends source: 'planner', where the base branch sent only task_count and types.

Two readings:

  • Intended: the PR body announces the property, and flag on and flag off still send the same shape, so this is fine.
  • Not intended: the stack promises no change with the flag off, and any insight that expects the old property set sees a change before anyone flips the flag.

If it's the second, gate the property behind the flag.

@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.

this is the change I'm sold on!! makes no sense to have the model reconstruct the graph every run :)

@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 - findings inline.

@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 - findings inline.

edwinyjlim and others added 2 commits November 12, 2026 11:27
The recorder took each prompt's flow and id from the downloaded agent menu
and joined them into the path it wrote. A flow or id is now one path
segment, and every destination is checked before a prompt is fetched or a
fixture is replaced.

Co-Authored-By: Claude <noreply@anthropic.com>
@edwinyjlim edwinyjlim added the security-review Request a security review label Nov 12, 2026
@posthog-security-review-bot

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

Copy link
Copy Markdown

✅ Security review complete — bd374b5eae4f

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 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

@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.

good stuff. some error handling stuff to address

edwinyjlim and others added 3 commits November 12, 2026 20:44
… own failure

A declared graph that cannot be ordered, or that a queue guard rejects,
ends the run with PHW_AGENT_ORCHESTRATOR_TASK_GRAPH and a message for
the user, and sends `orchestrator task graph rejected` with the reason.

A run queued from its frontmatter that queues nothing says the setup
had no steps to run.

A `dependsOn` name the flow does not declare is logged once when the
graph is queued.

A full-run test queues a warehouse task before the frontmatter graph:
it runs after the declared tasks, and the report waits for it.

Co-Authored-By: Claude <noreply@anthropic.com>
edwinyjlim and others added 2 commits November 13, 2026 11:35
The 49 prompts are the ones 1.64.0 published, byte for byte. The agent
menu changes only in the release its download URLs name.

Co-Authored-By: Claude <noreply@anthropic.com>
@edwinyjlim
edwinyjlim merged commit 1097024 into main Nov 13, 2026
32 checks passed
@edwinyjlim
edwinyjlim deleted the dag/3-queue-from-frontmatter 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