Skip to content

wire-in: StrategyPlanner → skill_router for plan-time skill resolution (ADR-006) #7268

Closed

Description

@mrveiss

Discovered during

ADR-006 drafting (2026-05-08) — articulating AutoBot's task-decomposition flow and finding that the live planner (StrategyPlanner) and the live skill resolver (skill_router) are not connected.

Finding

enhanced_orchestration.workflow_planning.StrategyPlanner is AutoBot's actively-used workflow planner (instantiated at orchestrator.py:251, consumed by workflow_runner.py:38). It produces WorkflowPlan objects whose steps target agents by AgentCapability via a static CAPABILITY_MAPPING.

Meanwhile, skills/builtin/skill_router.py is a 3-phase meta-skill that resolves a task description to a concrete BaseSkill:

  1. Phase 1 — keyword scoring against registered skills
  2. Phase 2 — LLM re-ranking of top-K candidates
  3. Phase 3 — gap-fill via skill-researcher + autonomous-skill-development + governance

StrategyPlanner does not import or call skill_router. WorkflowExecutor does not either. As a result:

  • The SkillRegistry is invisible to the planner
  • Capability gaps surface only at execution time (after planning has committed)
  • The Phase 3 learning loop (skill-researcher → autonomous-skill-development) is dormant for the planning path

Decision context

ADR-006: Skill-Bound Planning articulates the target state: the planner consults skill_router per step at plan time, binding each step to a concrete (skill_name, action) before the plan is finalized. Phase 3 is the learning loop that fills capability gaps.

This issue is the wire-in to realize ADR-006 against the active planner.

Sibling issue

#6820 tracks the orphan orchestration/workflow_planner.py (282 LOC, zero production callers — the dead twin of StrategyPlanner). #6820's resolution (wire-in or retire) is independent of this issue. Do not confuse the two; the active planner this issue targets is StrategyPlanner.

Acceptance criteria

  • StrategyPlanner.build_workflow_plan (or a successor method) iterates each produced step and resolves it via skill_router.execute("route", {"task": <step intent>})
  • Resolved (skill_name, action) is attached to the step (new field on the active WorkflowStep / AgentTask shape; coordinate with refactor: unify 5 duplicate WorkflowStep/Task/Plan definitions + add first-class prompt/tools fields #6951 follow-ups before adding the field)
  • When skill_router Phase 3 fires (no skill match), the planner handles the response per ADR-006 — preferred default is async (return WorkflowPlan in BLOCKED_ON_SKILL_GENERATION state with pending_skill_id)
  • WorkflowExecutor consumes the bound plan: per step, SkillRegistry.get(skill_name).execute(action, params) is invoked instead of (or in addition to) capability-based agent dispatch
  • Integration test: a known-skill task plans and executes end-to-end through the new path
  • Integration test: an unknown-capability task triggers Phase 3, demonstrates the learning loop synthesizing and registering a skill, then completes execution
  • ADR-006 status flipped from "Proposed" to "Accepted" at merge

Open questions (from ADR-006, must resolve before/during implementation)

  1. Sync vs async gap-fill default — async preferred, but executor needs a resume path
  2. skill_router cache policy — per-session, per-tenant, or global? Invalidation on new skill registration?
  3. Behavior when previously-resolved skill is removed/disabled between plan and execution — re-route at execution time, or fail the step?

Dependencies

  • #6951 follow-ups must settle before adding a skill_name field to the canonical step type — otherwise the field is added to the wrong class. Specifically, #7121 (lifecycle methods on canonical) is the most relevant precondition.
  • #6820 (orphan workflow_planner.py) is independent but should not be conflated with this work.

Priority

P2 — no current functional regression, but blocks the planning path from benefiting from the existing skill-routing + learning-loop infrastructure. Realizes ADR-006.

Related

  • ADR-006: docs/adr/006-skill-bound-planning.md
  • Wire-in 2 (separate, smaller): adding optional skill_hint field to WorkflowTemplate step shape so authored templates can pre-bind skills (skips skill_router lookup for known mappings). May be filed separately if this issue scope grows.

Activity

  1. mrveiss commented on May 8, 2026

    @mrveiss
    OwnerAuthor

    Design-blocker resolution (ADR-006 → Accepted)

    The three open questions identified at filing time are now resolved in ADR-006. Status flipped from Proposed → Accepted.

    Q1: Sync vs async gap-fill default → ASYNC

    • Planner attaches pending_skill_id to affected step, returns WorkflowPlan in BLOCKED_ON_SKILL_GENERATION state
    • Executor subscribes to Redis pub-sub channel skill_promoted; on matching pending_skill_id, plan transitions RUNNABLE and resumes
    • Sync mode available behind flag PLAN_SYNC_GAP_FILL=true for batch / offline use cases

    Q2: skill_router cache policy → PER-TENANT, 1h TTL, registry-change invalidation

    Q3: Behavior when bound skill is unavailable at execute time → LATE RE-BIND, no Phase 3 at execute time

    • Executor re-routes via skill_router (Phase 1+2 only — keyword + LLM re-rank)
    • Plan-time binding is a hint, not a contract
    • Audit event emitted on re-bind
    • If Phase 1+2 also fails (would require fresh Phase 3 gap-fill at execute time), step fails with structured error (original skill, attempted re-route, gap)
    • Phase 3 (research → synthesize → govern) remains a planning-time concern by design

    Dependencies update:

    Implementation can now proceed. The skill_name / skill_action / pending_skill_id field additions go on canonical autobot_shared/workflow/types.py:WorkflowTask (per #7121 close). All aliases inherit automatically.

  2. mrveiss commented on May 10, 2026

    @mrveiss
    OwnerAuthor

    Phase 1 landed — ba934a72f (PR #7432)

    This issue stays OPEN. Phase 1 satisfies 2 of the 7 acceptance criteria; Phases 2 and 3 (filed as #7430 and #7431) cover the remaining 5.

    Phase 1 scope (now done)

    • ✅ StrategyPlanner.build_workflow_plan iterates each step and resolves it via skill_router.execute("find_skill", {"task": …, "dry_run": True})
    • ✅ Resolved (skill_name, action, method) attached to canonical WorkflowTask (3 new fields, defaults None)

    Conservative defaults chosen (deferring the 3 open ADR-006 questions)

    Open question Phase 1 choice
    Sync vs async gap-fill Neither at plan time (dry_run=True) — gap-fill is Phase 3's (#7431) async-resume problem
    Cache policy Per-planner (lazy-init + cache for planner lifetime) — per-session/per-tenant nuance is #7431
    Removed-skill behavior Deferred to Phase 2 (#7430) — executor will check at dispatch time

    Remaining acceptance criteria

    When this issue closes

    Once #7430 and #7431 land, this issue closes with a roll-up proof comment (commit hashes for all 3 PRs + ADR-006 status update). Don't close before then — Phase 1 alone leaves the bound skill_name field unread by the executor, which is partial wire-in.

    7 regression tests on Phase 1 pin the contract for Phase 2/3 to extend safely:

    • WorkflowTask field surface
    • build_workflow_plan async signature
    • dry_run=True always passed (no auto-enable at plan time — load-bearing for Phase 3 design)
    • Success populates fields; failure/exception/missing-router leaves None (legacy fallback intact)
  3. mrveiss commented on May 10, 2026

    @mrveiss
    OwnerAuthor

    Phase 2 landed — e7efc6a61 (PR #7468)

    5 of 7 acceptance criteria on this issue now met. Issue stays OPEN until #7431 (Phase 3 async gap-fill resume) ships.

    Phase 2 scope (now done — see #7430 closure)

    • ✅ WorkflowExecutor (WorkflowRunner._execute_single_agent_task) checks task.skill_name first; if set, dispatches via SkillRegistry.get(skill_name).execute(action, params) instead of the capability-based agent path
    • ✅ ADR-006 Q3 resolved: skill-bound execution replaces agent dispatch (chosen over "alongside") and missing/disabled skills at execute time fail the step (chosen over "re-route") so plans can be re-planned upstream cleanly

    Wire-in now complete plan-time → execute-time

    StrategyPlanner.build_workflow_plan          (#7268 Phase 1, ba934a72f)
      → skill_router.execute("find_skill", dry_run=True)
      → task.skill_name / skill_action / skill_resolution_method populated
    
    WorkflowRunner._execute_single_agent_task    (#7430 Phase 2, e7efc6a61)
      → if task.skill_name: _dispatch_via_skill(task, context)
           → SkillRegistry.get(skill_name)  (validate registered+enabled, else fail)
           → await skill.execute(skill_action, enhanced_inputs)
      → else: legacy capability-based agent dispatch (unchanged)
    

    Acceptance progress (cumulative)

    Testing — 12 regression tests now pin the contract across both phases

    • 7 in workflow_planning_test.py (Phase 1 surfaces)
    • 5 in workflow_runner_test.py (Phase 2 dispatch paths)
    • All 12 pass; full workflow_runner_test.py 11/11 pass with no regressions on the 6 existing tests

    What's left

    #7431 needs owner input on:

    1. Cache policy for skill_router (per-session vs per-tenant vs global)
    2. Sync vs async gap-fill default (Phase 1 picked async-via-blocked-state; feat(orchestration/planner): async gap-fill resume path for blocked plans (#7268 Phase 3) #7431 implementation still owes the worker resume path)

    Once #7431 ships, this issue closes with a roll-up proof comment for all 3 PRs (#7432 + #7468 + the eventual #7431 PR) + ADR-006 status update.

  4. mrveiss commented on May 16, 2026

    @mrveiss
    OwnerAuthor

    ✅ Closed: merged in PR #7760 (commit 972f7b1).

    Acceptance Criteria Met:

    • ✅ ADR-006 Skill-Bound Planning document added to docs/adr/
    • ✅ ADR format followed with context, decision, consequences, and status fields
    • ✅ Merged to Dev_new_gui branch
  5. mrveiss commented on May 16, 2026

    @mrveiss
    OwnerAuthor

    Integration tests for Phases 2+3 are now merged to Dev_new_gui.

    Commit: 0ef0ae0 — test(enhanced_orchestration): Phase 2+3 integration tests for GH#7268 — merged via PR #7770 at 2026-05-16T13:33:44Z

    Tests cover:

    • Phase 2: skill dispatch via SkillRegistry (4 tests including E2E execute_workflow with skill-bound plan)
    • Phase 3: unknown-capability → BLOCKED plan → try_resume_blocked_plan → execution (5 tests)
    • BlockedPlanResumer event handling (2 tests)

    Note: GH#7268 was already closed by ADR-006 PR #7760. This comment records completion of the integration test deliverable tracked in MVA-419.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions