Skip to content

feat(autopilot): maintainer canvas, panel-mode, and comment writer - #3024

Merged
Daniel Meppiel (danielmeppiel) merged 5 commits into
mainfrom
sergio-sisternes-epam-autopilot-maintainer-canvas
Sep 18, 2026
Merged

Daniel Meppiel (danielmeppiel) merged 5 commits into
mainfrom
sergio-sisternes-epam-autopilot-maintainer-canvas

Conversation

@sergio-sisternes-epam

Copy link
Copy Markdown
Collaborator

feat(autopilot): maintainer canvas, panel-mode, and comment writer

TL;DR

This adds a CODEOWNER Autopilot maintainer canvas, a sole GitHub comment writer (autopilot-comment), cheaper panel-mode for PR review, and plan-first merge-worker. The canvas never assigns, requests reviewers, merges, or runs autopilot skills in the parent session.

Note

Rebased onto main after #3003 merged (98c0ed6a). Unique commit is 202d67662.

Problem (WHY)

  • Maintainers had no Copilot App surface to accept/defer/panel-review and spawn isolated schedulers/workers without running skills in the CODEOWNER session.
  • Issue/PR triage posted via gh issue/pr comment, so comments shipped without the AI footer (for example Docs: update stale README links #3017).
  • autopilot-pr-review-worker spawned the full roster (including inactive stubs) on every merge-worker iteration, including terminal no-signal reruns.

Why these matter: autopilot skills are supposed to be summoned by name and stay advisory, with a single comment writer. Agent Skills: "Add what the agent lacks, omit what it knows". PROSE: "Grounding outputs in deterministic tool execution transforms probabilistic generation into verifiable action.".

Approach (WHAT)

# Fix
1 New package packages/autopilot/autopilot-maintainer-canvas -- live GitHub lanes, human labels vs advisory labels, isolated create_session spawns, occupancy from Copilot data.db.
2 New skill autopilot-comment -- one post/patch, AI footer, no labels/assign/merge. Triage workers and schedulers pass comment_via: autopilot-comment.
3 Review worker panel-mode: full / lean / delta (unknown -> lean). Fast-path default include; orchestrator may add personas with adhoc_reason. Shared brief once. No inactive stubs.
4 Merge-worker plans first (scope vs work, fresh panel, fold, CI via agent-merge when present). Canvas spawn uses kickoff_mode: plan. Never merge. Never request the implementer as reviewer.
5 Desktop/wide canvas keeps action buttons in a right-hand column (no 6-col table clipping).

Implementation (HOW)

  • packages/autopilot/autopilot-maintainer-canvas/ -- Copilot canvas extension (ui.mjs, logic.mjs, server-handler.mjs). Parent only labels and create_session. Open uses ghapp://sessions/<id>. No Archive control.
  • packages/autopilot/autopilot-comment/ -- sole comment assembler/writer; source_skill in the footer.
  • packages/autopilot/autopilot-pr-review-worker/ -- roster, shared brief, schemas, panel-mode.md.
  • packages/autopilot/autopilot-pr-merge-worker/assets/worker-prompt.md -- Step 0.P plan-first; one full panel per run unless panel_escalation.
  • Issue/PR triage scheduler + worker SKILL.md -- comment_via; stop if the comment skill is missing; do not call gh issue/pr comment.
  • .agents/skills/ -- deployed copies; apm.lock.yaml hashes refreshed for changed files.
  • docs/src/content/docs/integrations/canvas.md -- maintainer canvas pointer.
  • packages/autopilot/README.md -- map updated (autopilot-comment, panel-mode, plan-first merge). Root README.md untouched.

Diagrams

Legend: canvas clicks stay in the parent; schedulers and workers run isolated; only autopilot-comment writes GitHub comments.

sequenceDiagram
    participant M as Maintainer
    participant C as autopilot-maintainer canvas
    participant P as CODEOWNER parent session
    participant S as Isolated scheduler
    participant W as Isolated worker
    participant AC as autopilot-comment
    participant GH as GitHub

    M->>C: Accept or spawn
    C->>P: spawn-isolated-session card
    Note over P: do_not_run_here
    P->>S: create_session coordinate_with_creator false
    S->>W: FANOUT 2 worker sessions
    rect rgb(255, 247, 200)
        Note over W,GH: NEW comments only via autopilot-comment
        W->>AC: load in same session
        AC->>GH: one comment plus footer
    end
    Note over P,S: never assign, request reviewers, or merge
Loading

Legend: merge-worker panel cost -- one full (or lean if tiny), then delta; terminal noop when head and watermark match.

flowchart LR
    subgraph mergeWorker [autopilot-pr-merge-worker]
      P0[Plan vs original scope]
      I1[Iteration 1 panel-mode full or lean]
      D[Iteration 2 plus delta]
      T[Terminal delta or noop]
      CI[agent-merge or gh pr checks watch]
    end
    P0 --> I1 --> D --> T
    D --> CI
    T --> CI
    classDef new stroke-dasharray: 5 5
    class P0,I1,D,T new
Loading

Trade-offs

  • Rebased onto main after feat(autopilot): origin-aware skills with CODEOWNERS-safe review #3003 merged. Chose --onto origin/main so this PR is one commit (202d67662), not a replay of the squash-merged stack.
  • Comment skill is source plus .agents copy, not yet a lock dependency. Workers branched from default still miss the file until this lands; kickoff cards carry comment_via as a standing override.
  • Canvas occupancy reads Copilot App data.db. Chose live session names over GitHub issue state so Refresh does not session.send.
  • No Archive on the canvas. Chose Open-only after the archive UX proved poor; cascade archive stays a chat action.
  • panel-mode unknown -> lean. Fail cheap, not fail heavy.

Out of scope

This PR does not edit the root README.md, does not resurrect deleted alias packages, and does not let the parent session run autopilot skills. Merge-worker still never calls gh pr merge.

Benefits

  1. CODEOWNERS can accept/defer/panel-review and spawn FANOUT=2 isolated workers without running skills in this session.
  2. Every autopilot GitHub comment can carry Generated by <source_skill>. This comment is AI-generated and may contain errors.
  3. Review panels stop spawning inactive stubs; merge-worker does not pay a full roster on every CI retry.
  4. Merge-worker starts in plan mode and still never merges or requests the implementer as reviewer.
  5. Desktop canvas action buttons stay in a clickable right column.

Validation

Lint (CI-mirror subset that applies):

uv run --extra dev ruff check src/ tests/ scripts/lint_architecture_boundaries.py scripts/architecture_linter/
All checks passed!
uv run --extra dev ruff format --check src/ tests/ scripts/lint_architecture_boundaries.py scripts/architecture_linter/
1869 files already formatted
pylint R0801: 10.00/10
scripts/lint-auth-signals.sh: [+] auth-signal lint clean
Canvas and unit tests
node --test packages/autopilot/autopilot-maintainer-canvas/tests/*.test.mjs
tests 43
pass 43
fail 0

uv run --extra dev pytest tests/unit/test_triage_advisory.py tests/unit/test_triage_fetch_queue.py tests/unit/test_workflow_actor_contract.py -q
44 passed in 0.69s

Scenario Evidence

# Scenario (user promise) Principle(s) Test(s) proving it Type
1 Canvas spawn asks the parent for create_session and never merge/assign DevX (pragmatic as npm) / OSS packages/autopilot/autopilot-maintainer-canvas/tests/logic.test.mjs spawn contract; tests/server.test.mjs has no archive endpoint unit
2 Merge worker starts in plan mode; review worker first advisory is panel-mode: full DevX / Governed by policy logic.test.mjs starts the merge worker in plan mode; asks the review worker for panel-mode full unit
3 Triage comments go through autopilot-comment; scheduler write: off, workers write: on Secure by default / OSS logic.test.mjs routes triage comments through autopilot-comment; tests/unit/test_workflow_actor_contract.py unit
4 Installed triage worker files match package sources and lock hashes Governed by policy tests/unit/test_triage_advisory.py::test_installed_skill_files_and_recorded_hashes_match_sources unit

How to test

  • Open this branch's Autopilot maintainer canvas in Copilot App. Decide lane shows issues/PRs. Accept/Defer/Panel-review sit in a right-hand column on desktop.
  • Click a scheduler spawn. A child session named Issue triage scheduler or PR triage scheduler starts; this parent does not run the skill. Occupancy shows Working.
  • After a triage worker comments, the GitHub body ends with Generated by autopilot-*-triage-worker. This comment is AI-generated and may contain errors.
  • Spawn merge-worker for an accepted PR. Session starts in plan mode; no merge and no --add-reviewer of the implementer.
  • Confirm this PR's base is main and the diff is the canvas/comment/panel-mode commit only (not a replay of feat(autopilot): origin-aware skills with CODEOWNERS-safe review #3003).

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Add the CODEOWNER Autopilot maintainer canvas, route GitHub comments
through autopilot-comment, add review panel-mode (full/lean/delta),
and make merge-worker plan before fold or CI.

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

Copilot AI 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.

🟡 Changes recommended

Critical lockfile, dependency, and roster-path issues remain unresolved, along with additional comment and canvas correctness findings.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds a maintainer canvas, centralized comment writer, configurable review panels, bot-triage updates, and plan-first merge-worker orchestration.

Changes:

  • Adds isolated canvas workflows and occupancy tracking.
  • Routes autopilot comments through autopilot-comment.
  • Adds panel modes, shared briefs, and merge planning.
  • Updates skills, tests, documentation, and deployed copies.
File summaries
File Reviewed change / finding
tests/unit/test_workflow_actor_contract.py Validates comment-writer contracts.
tests/unit/test_triage_fetch_queue.py Covers bot-authored PR eligibility.
tests/unit/test_triage_advisory.py Covers debug-card behavior.
packages/autopilot/README.md Nit, 1 vote: sole-writer claim omits a direct gh pr comment path.
packages/autopilot/autopilot-pr-triage-worker/apm.yml Adds autopilot-comment dependency; Critical, 1 vote: lockfile entry is missing.
packages/autopilot/autopilot-pr-triage-worker/.apm/skills/autopilot-pr-triage-worker/SKILL.md Routes PR comments through the writer.
packages/autopilot/autopilot-pr-triage-worker/.apm/skills/autopilot-pr-triage-worker/assets/pr-triage-template.md Updates triage rendering.
packages/autopilot/autopilot-pr-triage-scheduler/.apm/skills/autopilot-pr-triage-scheduler/SKILL.md Updates bot and comment behavior.
packages/autopilot/autopilot-pr-triage-scheduler/.apm/skills/autopilot-pr-triage-scheduler/scripts/fetch_queue.py Preserves eligible PR filtering.
packages/autopilot/autopilot-pr-triage-scheduler/.apm/skills/autopilot-pr-triage-scheduler/assets/fan-out-pool.md Updates worker kickoff requirements.
packages/autopilot/autopilot-pr-review-worker/evals/fixtures/03-panel-mode-walkthrough.md Adds a panel-mode fixture.
packages/autopilot/autopilot-pr-review-worker/assets/shared-brief.example.json Adds a shared brief example.
packages/autopilot/autopilot-pr-review-worker/assets/recommendation-template.md Adds panel-mode rendering.
packages/autopilot/autopilot-pr-review-worker/assets/panelist-return-schema.json Updates panelist contract.
packages/autopilot/autopilot-pr-review-worker/assets/panel-mode.md Defines panel modes and rosters.
packages/autopilot/autopilot-pr-review-worker/assets/ceo-return-schema.json Adds panel metadata.
packages/autopilot/autopilot-pr-review-worker/apm.yml Adds comment-writer dependency.
packages/autopilot/autopilot-pr-review-scheduler/.apm/skills/autopilot-pr-review-scheduler/SKILL.md Requests full first-pass panels.
packages/autopilot/autopilot-pr-review-scheduler/.apm/skills/autopilot-pr-review-scheduler/assets/fan-out-pool.md Updates review kickoff.
packages/autopilot/autopilot-pr-merge-worker/SKILL.md Adds plan-first and CI rules.
packages/autopilot/autopilot-pr-merge-worker/assets/worker-prompt.md Defines planning and panel iteration.
packages/autopilot/autopilot-pr-merge-worker/assets/completion-schema.json Adds panel metadata.
packages/autopilot/autopilot-pr-merge-worker/assets/ci-recovery-checklist.md Documents CI recovery.
packages/autopilot/autopilot-pr-merge-worker/apm.yml Adds comment-writer dependency.
packages/autopilot/autopilot-maintainer-canvas/tests/server.test.mjs Tests canvas server behavior.
packages/autopilot/autopilot-maintainer-canvas/tests/logic.test.mjs Tests canvas logic and spawn contracts.
packages/autopilot/autopilot-maintainer-canvas/README.md Documents canvas installation.
packages/autopilot/autopilot-maintainer-canvas/apm.yml Defines canvas metadata.
packages/autopilot/autopilot-maintainer-canvas/.gitignore Ignores generated files.
packages/autopilot/autopilot-maintainer-canvas/.github/copilot-instructions.md Adds package instructions.
packages/autopilot/autopilot-maintainer-canvas/.apm/extensions/autopilot-maintainer/server-handler.mjs Moderate, 1 vote: normalize null bodies, drain oversized requests, and add tests to CI.
packages/autopilot/autopilot-maintainer-canvas/.apm/extensions/autopilot-maintainer/extension.mjs Moderate, 1 vote each: include comment-only receipts and paginate issue listings.
packages/autopilot/autopilot-maintainer-canvas/.apm/extensions/autopilot-maintainer/copilot-sessions.mjs Critical, 2 votes: preserve occupancy when SQLite reads fail.
packages/autopilot/autopilot-issue-triage-worker/SKILL.md Adds debug output and comment routing.
packages/autopilot/autopilot-issue-triage-worker/assets/triage-template.md Updates triage output.
packages/autopilot/autopilot-issue-triage-worker/apm.yml Critical, 1 vote: comment dependency is absent from the lockfile.
packages/autopilot/autopilot-issue-triage-scheduler/.apm/skills/autopilot-issue-triage-scheduler/SKILL.md Updates worker kickoff.
packages/autopilot/autopilot-issue-triage-scheduler/.apm/skills/autopilot-issue-triage-scheduler/scripts/fetch_queue.py Preserves issue filtering.
packages/autopilot/autopilot-issue-triage-scheduler/.apm/skills/autopilot-issue-triage-scheduler/assets/fan-out-pool.md Adds comment-writer requirements.
packages/autopilot/autopilot-comment/SKILL.md Adds centralized comment assembly and writing.
packages/autopilot/autopilot-comment/apm.yml Defines comment-writer metadata.
docs/src/content/docs/integrations/canvas.md Documents the maintainer canvas.
CHANGELOG.md Nit, 3 votes: entries need PR-number suffixes and one line per PR.
apm.lock.yaml Critical, 2 votes: missing review-worker files and autopilot-comment dependency must be regenerated.
.github/workflows/triage-panel.md Moderate, 1 vote: direct safe-outputs.add-comment bypasses the sole writer.
.agents/skills/autopilot-pr-triage-worker/SKILL.md Deploys PR-triage changes.
.agents/skills/autopilot-pr-triage-worker/assets/pr-triage-template.md Deploys the updated template.
.agents/skills/autopilot-pr-triage-scheduler/SKILL.md Deploys scheduler changes.
.agents/skills/autopilot-pr-triage-scheduler/scripts/fetch_queue.py Deploys queue filtering.
.agents/skills/autopilot-pr-triage-scheduler/assets/fan-out-pool.md Deploys fan-out rules.
.agents/skills/autopilot-pr-review-worker/SKILL.md Moderate, 1 vote: workflow still writes directly; Critical, 1 vote: roster paths resolve incorrectly.
.agents/skills/autopilot-pr-review-worker/evals/fixtures/03-panel-mode-walkthrough.md Deploys the panel fixture.
.agents/skills/autopilot-pr-review-worker/assets/shared-brief.example.json Deploys the shared brief example.
.agents/skills/autopilot-pr-review-worker/assets/recommendation-template.md Deploys recommendation changes.
.agents/skills/autopilot-pr-review-worker/assets/panelist-return-schema.json Deploys schema changes.
.agents/skills/autopilot-pr-review-worker/assets/panel-mode.md Deploys the panel-mode contract.
.agents/skills/autopilot-pr-review-worker/assets/ceo-return-schema.json Deploys CEO schema changes.
.agents/skills/autopilot-pr-review-worker/apm.yml Deploys dependency metadata.
.agents/skills/autopilot-pr-review-scheduler/SKILL.md Deploys review scheduler changes.
.agents/skills/autopilot-pr-review-scheduler/assets/fan-out-pool.md Deploys review fan-out rules.
.agents/skills/autopilot-pr-merge-worker/SKILL.md Deploys merge-worker rules.
.agents/skills/autopilot-pr-merge-worker/assets/worker-prompt.md Deploys merge planning.
.agents/skills/autopilot-pr-merge-worker/assets/completion-schema.json Deploys completion schema.
.agents/skills/autopilot-pr-merge-worker/assets/ci-recovery-checklist.md Deploys CI checklist.
.agents/skills/autopilot-pr-merge-worker/apm.yml Deploys dependency metadata.
.agents/skills/autopilot-issue-triage-worker/SKILL.md Deploys issue-worker changes.
.agents/skills/autopilot-issue-triage-worker/assets/triage-template.md Deploys issue template changes.
.agents/skills/autopilot-issue-triage-worker/apm.yml Deploys issue-worker metadata.
.agents/skills/autopilot-issue-triage-scheduler/SKILL.md Deploys issue scheduler changes.
.agents/skills/autopilot-issue-triage-scheduler/scripts/fetch_queue.py Deploys issue queue changes.
.agents/skills/autopilot-issue-triage-scheduler/assets/fan-out-pool.md Deploys issue fan-out rules.
.agents/skills/autopilot-comment/SKILL.md Deploys the comment writer.
.agents/skills/autopilot-comment/apm.yml Deploys comment-writer metadata.
Review details

Suppressed comments (8)

.github/workflows/triage-panel.md:255

  • This step still instructs the workflow to emit the comment directly through safe-outputs.add-comment, then separately says to post through autopilot-comment. That bypasses the new assembler/footer and permits two competing write paths; make the autopilot-comment activation the sole comment write instead of calling the safe output here.
   no-op. Otherwise emit exactly one public comment through
   `safe-outputs.add-comment`. Default `debug: off`: keep the filled
   receipt line (`target` plus `watermark`) and the Suggested issue
   comment body only (unwrap the markdown fence). Do not post

packages/autopilot/README.md:26

  • This broad sole-writer claim is not true for all autopilot comments: autopilot-issue-delivery-worker/.apm/skills/autopilot-issue-delivery-worker/references/strategic-alignment-gate.md:135 still executes gh pr comment directly. That path bypasses the new footer and violates the stated ownership contract; route it through autopilot-comment or narrow this claim.
    packages/autopilot/autopilot-maintainer-canvas/.apm/extensions/autopilot-maintainer/extension.mjs:54
  • Because comment-only advice has no triage/recommended label, this filter never fetches its comments, so the canvas can show an item as Not triaged even though applyTriageAdvice supports a comment-only receipt. Include all non-accepted items in this fetch (or otherwise detect comment-only receipts).
    packages/autopilot/autopilot-maintainer-canvas/.apm/extensions/autopilot-maintainer/extension.mjs:87
  • The canvas hard-caps the issue query at 100, but the repository currently has 154 open issues, so at least 54 never appear in the purported live GitHub queue. Paginate the issue/PR listings (or provide continuation) before shipping the maintainer surface.
    packages/autopilot/autopilot-maintainer-canvas/.apm/extensions/autopilot-maintainer/server-handler.mjs:73
  • JSON.parse(raw) can return null; /label and /spawn then dereference body.isPayloadTooLarge outside their try blocks. A valid JSON null request therefore hangs or resets instead of returning the existing 400/409 error response. Normalize parsed bodies to a non-array object (or reject non-objects) here.
    packages/autopilot/autopilot-maintainer-canvas/.apm/extensions/autopilot-maintainer/server-handler.mjs:5
  • These new canvas tests are not included in the repository's Node CI step: .github/workflows/ci.yml:125-129 enumerates only the contributor-dashboard tests. The extension therefore has no automated merge gate despite adding executable server/SQLite behavior; include packages/autopilot/autopilot-maintainer-canvas/tests/*.test.mjs in the existing Node test commands.
    packages/autopilot/autopilot-maintainer-canvas/.apm/extensions/autopilot-maintainer/server-handler.mjs:49
  • When the request exceeds the limit, this path removes every request listener and rejects without draining the remaining body. On a keep-alive connection, unread bytes can leave the local server stalled or poison the connection for the next request. Drain the request before rejecting, as the existing dashboard handler does.
    packages/autopilot/autopilot-pr-review-worker/SKILL.md:59
  • The Agentic Workflow still tells this worker to emit its PR comment via safe-outputs.add-comment (.github/workflows/pr-review-panel.md:230-236). With this new contract, that caller bypasses autopilot-comment and its required footer. Update the workflow caller so the worker activates autopilot-comment rather than writing the safe output itself.
  • Files reviewed: 76/76 changed files
  • Comments generated: 5
  • Review effort level: Lite

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apm.lock.yaml Outdated
Comment thread packages/autopilot/autopilot-issue-triage-worker/apm.yml
Comment thread packages/autopilot/autopilot-pr-review-worker/SKILL.md Outdated
Comment thread CHANGELOG.md Outdated
Keep apm.lock.yaml content hashes aligned with deployed skill bytes after
the maintainer-canvas skill edits, and recompile triage-panel so body_hash
matches source. Retain existing gh-aw 0.87.8 action pins alongside 0.88.2.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Record autopilot-comment and new review-worker assets in apm.lock.yaml.
Keep occupancy when Copilot data.db is unreadable. Point the review
roster at .apm/agents. Number the Unreleased changelog lines for #3024.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@sergio-sisternes-epam Sergio Sisternes (sergio-sisternes-epam) added triage/recommended Automated advice completed; not human scope approval. status/deferred Not invited for implementation now; no release commitment. type/feature New capability, new flag, new primitive. theme/governance Governed by policy. apm-policy, audit, enforcement, enterprise rollout. labels Sep 18, 2026
@sergio-sisternes-epam

Copy link
Copy Markdown
Collaborator Author

Thank you for contributing this pull request. APM starts with an
issue, not an implementation
(https://github.com/microsoft/apm/blob/main/CONTRIBUTING.md).
Please open an issue describing the user problem so a maintainer
can review and accept the scope first. This PR is labelled
status/deferred until that happens.

CODEOWNERS owners are Daniel Meppiel (@danielmeppiel) and Sergio Sisternes (@sergio-sisternes-epam).
Runtime reviewRequests currently include Daniel Meppiel (@danielmeppiel). This
comment does not add or remove reviewers.

#3003 is a rebase note only, not a linked issue for
this PR. GitHub closingIssuesReferences is empty. Neither this PR
nor a same-repo linked issue is labelled status/accepted.

This is advisory classification only. It is not merge approval,
scope acceptance, assignment, or a request to run a review panel.


Generated by autopilot-pr-triage-worker. This comment is AI-generated and may contain errors.

Stop skipping Bot authors in issue triage so Copilot/Dependabot/Actions
issues enter the same queue as human work. Recompile triage-panel with
gh-aw v0.87.8 so CI matches the repo pin.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@danielmeppiel
Daniel Meppiel (danielmeppiel) merged commit 98616b9 into main Sep 18, 2026
28 checks passed
@danielmeppiel
Daniel Meppiel (danielmeppiel) deleted the sergio-sisternes-epam-autopilot-maintainer-canvas branch September 18, 2026 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status/deferred Not invited for implementation now; no release commitment. theme/governance Governed by policy. apm-policy, audit, enforcement, enterprise rollout. triage/recommended Automated advice completed; not human scope approval. type/feature New capability, new flag, new primitive.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants