Skip to content

feat(planner): /planner skill - grounded ESS rollout planning (Step 1) - #220

Open
harsheetjain wants to merge 13 commits into
microsoft:mainfrom
harsheetjain:harsheetjain/adk-plan-generation-step1
Open

feat(planner): /planner skill - grounded ESS rollout planning (Step 1)#220
harsheetjain wants to merge 13 commits into
microsoft:mainfrom
harsheetjain:harsheetjain/adk-plan-generation-step1

Conversation

@harsheetjain

Copy link
Copy Markdown

Adds the /planner skill and scripts/planner package - Step 1 of the ADK plan-generation dev spec.

  • Grounded Microsoft Learn (Table-of-Contents) research selection.
  • Grounded interview -> atomic, Learn-grounded-role tasks; Flow 1 (assign a person to a role) and Flow 2 (discover my tasks grouped by role).
  • Observe/ask output capture (the /setup -> environmentId hand-off).
  • Scenario dependencies modeled in the open Context bag (PM spec: HR knowledge before HR ticketing).
  • Local-first; shaped to sync to the WeveNova Plan/Task entities. 64 tests.

Design: dev-specs/adk-plan-generation/.

harsheetjain and others added 6 commits August 4, 2026 14:38
…Step 1)

Implements Step 1 of the ADK plan-generation dev spec: a local-first,
structured Plan the /planner skill authors for an ESS rollout.

- scripts/planner/: Plan model (atomic IO, validation, summary render, Flow-2
  grouped-by-role discovery), TOC-first Microsoft Learn research selection,
  observe-mode output capture (/setup -> environmentId from config.json), an
  absent-safe roles-source seam, and a CLI the skill drives.
- src/skills/planner/ + planner.prompt.md: the grounded interview ->
  Learn-grounded roles/tasks -> Flow-1 person assignment -> capture playbook,
  wired into copilot-instructions routing and the menu. Planner is the one
  experience allowed before setup (planning decides a greenfield deployment).
- tests/planner/: 49 tests (pure logic + local IO; no network/cassettes).
- dev-specs/adk-plan-generation/: the design doc.

The local Plan is shaped like the WeveNova Plan/Task entities so a future sync
is a field copy. WeveNova, tenant inventory, and the roles source are all
optional, absent-safe seams; the Plan is authoritative on disk without them.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Capture and expose scenario-to-scenario ordering (the PM spec's "HR knowledge
before HR ticketing") without a new typed collection, consistent with the
one-Context-bag model:

- A scenario in scope is a Context entry (group "scenario"); a dependency edge
  is a Context entry (group "scenarioDependsOn", key "A -> B", scalar value =
  kind requires|recommends, description = rationale/PM-spec citation).
- A grounded PM-spec seed (knowledge -> ticketing) lets the planner advise the
  sponsor; unmet_scenario_dependencies() surfaces prerequisites not in scope.
- Exposed via the interview (check-deps) and rendered in summary with a
  met/MISSING status; ordering is then enforced by the task produces/consumes
  DAG.
- New CLI: add-scenario, add-scenario-dependency, check-deps. 15 new tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ct onboarding framing

- Routing: greenfield "set up ESS for the first time / where do I start / how do
  I get started" now routes to /planner (not /setup); the planner emits "run
  /setup" as the first task. Added the gate exception + trigger phrases.
- Onboarding framing: /setup (onboarding) connects the kit to an ALREADY-deployed
  ESS agent and records its details - it does not create the environment or
  install ESS (those are portal/admin prerequisites on a new tenant). Reworded
  model.md, capture.md, planner.prompt.md, capture.py docstring, and the dev-spec.
- Back-propagation documented: the details /setup records in .local/config.json
  (environmentId, dataverseEndpoint, agent slug/schema/folder) flow to later
  tasks via config.json (every skill reads it) and via the pinned
  primaryEnvironment artifact (tasks that consume it) - e.g. topic create.

Docs/framing only; no logic change. 64 tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ut, stronger skill steps

Addresses a real run that stopped after a single "run setup" task and skipped
the system/scenario questions:

- CLI: `task-brief` shows an assignee how to do a task, their role, the resolved
  values it consumes (e.g. the env id setup produced - the back-propagation), and
  the keys to capture. `pin-output` commits what an assignee created (Workday
  connection, Entra app, eval suite) onto the plan - the generic ask-mode
  counterpart to capture-setup.
- Model: Plan.resolved_consumes() + Plan.task_brief().
- Skill instructions made prescriptive so the agent runs the WHOLE flow: the
  interview must capture which systems + scenarios (mandatory) before Phase 3;
  Phase 3 emits the full grounded task set (setup + one connect per system +
  authoring per scenario + evals + publish), not just setup; Phase 5 briefs each
  assignee with the env id and commits what they create back onto the plan.
- 5 new tests (69 total).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…, check-deps, research extraction, summary timestamp

Ground the planner on the PM spec model (scenarios come from the maker + Microsoft Learn; a business-scenario catalogue is an optional implementation choice) and fix four greenfield smoke-test bugs.

Grounding:
- Remove the invented scenario_catalogue.json + catalogue.py (a business-scenario list the PM spec does not define).
- Add planner_facts.json + facts.py holding non-Learn facts ONLY: scenario dependencies (each with an explicit source) + a recognition lexicon. Not a scenario catalogue.
- known_scenario_dependencies() now reads the facts file; no false "PM spec" citation. The knowledge->ticketing edge is sourced "ess-design-guidance" and flagged confirm-citation (verified: absent from pm-spec.md and the ADO spec repo).
- Drop scenarios/suggest-scenarios CLI (prompt->fixed-list mapping).

Bug fixes:
- bug1: add-system CLI + Plan.set_system write scoped keys (system.<area>) so multiple target systems no longer collide on one reused key; interview.md asks per-area.
- bug2: check-deps + Plan.scenario_dependency_status() surface MET dependencies, not only unmet.
- bug3: research.extract_signals/strip_html/fetch_page_text + `research --extract` pull role/output candidates off fetched Learn pages.
- bug4: plan carries updatedAt (bumped on save); summary renders Generated + Updated.

Tests: 82 pass, 1 live skipped. Adds tests/planner/test_facts.py; updates scenario/research/cli/plan_model tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…connectors

The interview asked "which backend systems should ESS connect to" with improvised
examples (incl. ADP, which has NO native ESS connector). Ground the systems
capture in Phase-1 Learn research instead of improvising:

- Native ESS integrations = Workday, ServiceNow HRSD/ITSM, SAP SuccessFactors
  (each has an ESS Learn page in the TOC). Derive the set from research; don't
  name systems from memory.
- SharePoint / M365 content is a knowledge source, not a data-system connector.
- A system with no native connector (ADP, Jira, Dynamics 365, custom HTTP API)
  routes to /create (custom Power Automate flow), NOT a connect task.

model.md Phase 3 now emits a create task (not a fabricated connect task) for
non-native systems.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@harsheetjain
harsheetjain force-pushed the harsheetjain/adk-plan-generation-step1 branch from 9b05e7d to fd10d73 Compare August 4, 2026 09:10
harsheetjain and others added 7 commits August 4, 2026 14:42
If a plan already exists, /planner asked for the objective again because the
plan-existence check was buried at the bottom of SKILL.md (after the phases +
"the interview must capture the objective" emphasis).

- Promote plan lookup to the FIRST step ("First - resume or start"): if
  workspace/plan/plan.json exists, show its latest state (summary) and the tasks
  the person can pick up, role-gated (Flow 2), and do NOT re-run the interview or
  re-ask the objective. Start over only on explicit confirmation.
- A task is shown only if the person holds the role it needs; role resolution is
  best-effort until the roles source / MCP exists (future work).
- Frame the phases as "building a new / extending a plan"; reinforce the resume
  gate in planner.prompt.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ironment

/setup should be deliberate and plan-driven, not auto-fired by the gate. Drive it
from plan state:

- The Power Platform admin's setup task decides/creates the environment and pins
  primaryEnvironment. Every OTHER persona must connect their own kit to that same
  environment before their task's skill works.
- Plan.kit_setup_nudge(): for a non-setup kit-skill task, once primaryEnvironment
  is pinned, returns the env id/url to connect to; None for the setup task itself,
  non-kit tasks, or when no env is pinned yet (then the setup task is the
  prerequisite, not a nudge).
- task_brief surfaces it; the task-brief CLI prints "First connect your kit: run
  /setup and choose environment <envId>".
- Skill docs (mytasks/capture/model/SKILL) explain the plan-driven nudge.

Tests: 83 pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The gate's welcome told every user to "Type /setup", which is a VS Code prompt-file
command that does not exist in the Copilot CLI. Reword to name both surfaces: type
/setup in VS Code, or just say "set up ESS" in the CLI/any chat. The routing
exceptions already treat "explicitly asked to run setup" the same as /setup, so
natural-language invocation works.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ship the kit's CLI entry points inside the repo so anyone who clones it gets them
automatically (no per-user ~/.copilot copy or sync needed). The Copilot CLI
auto-discovers project skills from .github/skills/<name>/SKILL.md.

- solutions/ess-maker-skills/.github/skills/setup/SKILL.md
- solutions/ess-maker-skills/.github/skills/planner/SKILL.md

Names match the VS Code prompt-file commands (/setup, /planner) so the skill name
is consistent across Copilot in VS Code and the CLI. Each is a thin launcher that
honors the kit's copilot-instructions then follows the real
src/skills/{onboarding,planner}/SKILL.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tasks are assigned a Learn-grounded role at creation (the role that should be able
to pick the task). Make that grounding explicit and auditable:

- new_task / add-task gain --role-source: the Microsoft Learn URL that grounds the
  task's role (optional task.roleSource field). task_brief surfaces it as
  "Role grounded in: <url>".
- research.md: `research --extract` surfaces role candidates per page; carry the
  (role, source URL) pair into task creation.
- model.md: every task gets a Learn-sourced --role + --role-source at creation;
  the person is assigned later (Phase 4 / future external roles API).
- assign.md + dev-spec: document the future external roles API — RoleSource
  .list_holders resolves role->person, and a task can be assigned a user together
  with the role. The role stays Learn-grounded; the API only resolves people.

Tests: 85 pass (adds role-source coverage).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d it

When /setup finishes it now nudges the maker to record it on the rollout plan
instead of waiting for someone to notice.

- onboarding step3-flightcheck.md gains a plan-aware handoff (3.4): at the end of
  setup (readiness check skipped or done), if workspace/plan/plan.json exists,
  offer to mark the setup task complete and pin the environment, running
  `capture-setup --complete`. Plan-conditional, so standalone /setup users are
  unaffected.
- Plan.setup_task_id() finds the plan's /setup task (the onboarding-skill task,
  not a portal "provision" task). `capture-setup --task` is now optional and
  auto-detects it, so the handoff is turnkey.
- capture.md documents the auto-detect and the automatic offer.

Tests: 87 pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@harsheetjain
harsheetjain force-pushed the harsheetjain/adk-plan-generation-step1 branch from f8fe673 to c284468 Compare August 4, 2026 15:15
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