Repository navigation
Planner never sees the capability catalog: plan-time capability selection is the missing half of #20 #49
Description
Hypothesis
The planner is the right place to choose capabilities, and today it cannot: the prompt never mentions them and the plan has no field for them. If TaskPlanner received the registry's name+description pairs and emitted capabilities: [names] per task, self-assembly would start from the plan's choice instead of keyword inference, and the choice would be plan data a human can edit. This is the missing half of #20: the plan already says what runs after what (#35/#37); it should also say what each task runs with.
Evidence
Measured in the clone at 42f8e72 plus the #35/#37 stack:
lib/agentic/task_planner.rb:52-53: the system and user messages ask for "the type of agent best suited" and instructions. No capability names, no registry access;TaskPlanner#initializetakesgoal,llm_config,stream_callback,observer.- The strict output schema (
:55-70, extended by Planner emits dependency edges and output wiring (#20, part 2 of 3) #37 withid,depends_on,needs) has nocapabilitiesproperty.TaskDefinition#to_hhas nothing to serialize. AgentAssemblyEngine#analyze_requirements(:70-88) infers fromtask.descriptionandtask.agent_speconly. Self-assembly can't see the registry: keyword inference is a hardcoded 11-name list, and only 4 of 7 registered capabilities are on it #44 documents where that lands: 4 of 7 registered capabilities can ever be inferred.- Every capability's
descriptionis already written for a model to read (Capabilities::Examples). Eight of them at ~100 tokens each is ~800 tokens of prompt, the Agent Skills metadata tier.
Why this is Direction
"The plan is the product." A plan that names its capabilities is more inspectable (you can see why a task got web_search), more editable (swap it in the JSON), and more persistable (the store can resolve versions on load, #45). It is also how the self-assembly bet matures: assembly becomes "honor the plan, then fill gaps" instead of "guess from prose." LLMCompiler is the reference: planner sees tool descriptions, plan names tools, executor runs them. Research digest: #48, Finding 3.
Experiment that would validate it
TaskPlanner.new(goal, llm_config, registry: Agentic.capability_registry); when a registry is given, append a "Capabilities available" block (name: description) to the user message and addcapabilities: {type: "array", items: {type: "string"}}to the task schema. Unknown names are dropped with a warning, as Planner emits dependency edges and output wiring (#20, part 2 of 3) #37 does for malformed edges.TaskDefinitiongainscapabilities:(default[], serialized only when non-empty, so flat plans round-trip unchanged).AgentAssemblyEngine#analyze_requirementsseedsrequirements[:capabilities]fromtask.capabilitiesbefore inference.- Test that proves it: the four task descriptions from Self-assembly can't see the registry: keyword inference is a hardcoded 11-name list, and only 4 of 7 registered capabilities are on it #44's table planned against the registry; assert the plan names
summarization,brainstorming,structured_extraction, anddata_analysis+code_generationrespectively, and that assembly selects exactly those. Plus a round-trip spec and a no-registry spec showing byte-identical prompts.
Measurable claim: on #44's four descriptions the default strategy goes from 1/4 correct selections to 4/4, without touching the keyword list.
Cost
Prompt paragraph, one schema property, one TaskDefinition field, one line in the assembly engine, ~10 specs. No new dependencies. Depends on #35/#37 (schema plumbing) merging first; pairs with #44 but does not require it.
What it is not
Not function calling. The model chooses capabilities when it plans, not while it executes; that keeps the no-LLM-call-per-step cost profile. Whether a chosen capability then has an execution path is C7 in the digest, a separate question.
Class: code-feature (L0)
Minerva's lean: yes, and before #44: fixing inference improves a guess, while this replaces the guess with the plan.
Origin: loop:research session 2026-09-19. Intended labels: loop:research, status:analyzed.
Activity