jpicklyk/task-orchestrator/review-proposals

Claude Code and agent skill by jpicklyk/task-orchestrator

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Triages pending improvement-proposal MCP items - presents each with its scope and evidence, collects an accept/reject/defer decision per proposal, and carries out the disposition: project-scoped acceptances get their exact YAML applied to .taskorchestrator/config.yaml and pushed per-root; global acceptances get a tracked GitHub issue (or dwell in review for the maintainer); rejections are recorded and cancelled; deferrals are recorded and left in queue. Use when a user says: review proposals, t…

Install

npx vskill@latest install jpicklyk/task-orchestrator/review-proposals

SKILL.md

Review Proposals

Triages improvement-proposal MCP items created by /session-retrospective when a cross-session trend graduates. Presents pending proposals, collects a per-proposal decision, and carries out the disposition, including applying project-scoped config changes and filing or linking GitHub issues for global changes.

Calls are 4.0 tool calls; shapes live in `../_generated/call-shapes.md`. Every answer is the response envelope (ok, data or error). A write is {ops: [...]} of flat elements (one per to-call block here). Results come back as data.results[i] in request order with data.summary {ok, failed}; read ops of an ops tool (config get, validate, effective) answer there too. These calls are non-atomic: if any element fails, even in a one-element call, the answer is ok: false with top-level error.code: partial_failure (no detail, no fix) beside the full data, and the cause is that element's data.results[i].error (code, message, detail, fix). Any other top-level error.code is a call-level rejection (envelope, unknown field, access).

Shared GitHub conventions (issue template, scrub rule, gh guard, dedup procedure) are not duplicated here: see <skill-base-dir>/../session-retrospective/references/github-feedback.md for the C2/C4/C5 contract referenced in Step 5.


Step 0 - Parse Arguments and Read Config

Parse $ARGUMENTS:

  • A UUID: single-proposal mode. Skip Step 1 and go to Step 2 for that item.
  • `--scope global` or `--scope project`: run only that scope's discovery query. Otherwise run both.

Read the config file directly (a file read, not an MCP call): the path on the SessionStart context's Config: line when there is one, otherwise the workspace .taskorchestrator/config.yaml. In personal scope that path is the user-level file. Below, "the config file" is whichever you read here. Read:

  • project.rootId / project.name: enables the project-scoped discovery query and the per-root push in Step 5. In personal scope the root is the anchor-only personal root: skip the project-scoped discovery query (proposals live in the global container), but a project-scoped acceptance still edits and pushes the user-level file with rootId = the personal root. Without a rootId, project-scoped discovery and acceptance are unavailable; proceed global-only.
  • extensions.claude-code.retrospective.github_feedback.enabled: default false when the block or key is absent.
  • extensions.claude-code.retrospective.github_feedback.repo: default jpicklyk/task-orchestrator.

A leftover top-level retrospective: block is not read by the plugin and is rejected by a strict push (see Step 5, Accept - project-scoped).


Step 1 - Discovery

Skip in single-proposal mode. Run both queries in parallel (unless --scope narrows to one).

Global. Find the "Improvement Proposals" container, then read its children:

to-call
{"tool": "items_read", "select": "search", "args": {"query": "Improvement Proposals", "kinds": ["item"], "limit": 5}}

A search hit carries no depth, parent or type: take the hit titled exactly Improvement Proposals and confirm it is a root (items_read get, no parentId); a per-project container of that title sits under a project root and is not the global one.

to-call
{"tool": "items_read", "select": "overview", "args": {"anchorId": "<container-uuid>"}}

Project-scoped (only with a known project.rootId):

to-call
{"tool": "items_read", "select": "list", "args": {"tags": ["improvement-proposal"], "ancestorId": "<rootId>", "limit": 50}}
Partition results

Classify each candidate by role and notes:

  • Pending: role queue, no adoption-decision note yet. The main triage set.
  • Deferred: role queue, with an adoption-decision note whose body starts with "deferred". List separately; do not re-offer unless the user asks to revisit deferred proposals or the stated revisit condition plausibly holds now.
  • Stalled: role work (accepted and advanced by start but never reached review or terminal: an interrupted adoption). Flag as stalled adoption; offer to resume (fill remaining notes and complete) or cancel.
  • Awaiting verification: role review (accepted and applied; outcome-verification unfilled). List separately as ` <short-id> - awaiting verification (accepted <date from its adoption-decision note>) . No decision is offered: /session-retrospective Step 8a fills outcome-verification` once at least 2 later retrospectives exist.
  • Terminal: skip.

If nothing is pending (no queue-role item without an adoption-decision, and no stalled item), report No pending improvement proposals. and stop.


Step 2 - Load Proposal Detail

For each candidate (pending and stalled; cap 15, taking the 15 oldest by creation and noting the overflow), list its notes by key, then get the bodies that exist. A list carries no bodies.

to-call
{"tool": "notes_read", "select": "list", "args": {"itemId": "<uuid>", "keys": ["proposal", "adoption-decision"]}}
to-call
{"tool": "notes_read", "select": "get", "args": {"itemId": "<uuid>", "key": "proposal"}}

From the notes extract:

  • Proposal body: the proposal note (or the item's summary if the note is absent; an absent note is backfilled before any Accept, see Step 5).
  • Scope clause: the scope classification the note states (global or project-specific). If it cannot be parsed unambiguously, treat as global: never auto-edit a project's config on an ambiguous scope reading.
  • Existing `github-issue:` line: the last line of the proposal body, github-issue: <url>. Carry it forward so the global-accept path reuses it instead of filing a duplicate.

Step 3 - Present Triage Table

One compact table of all pending and stalled candidates; deferred proposals get a short list underneath.

| # | ID | Proposal | Scope | Evidence | Age | Issue |
|---|-----|----------|-------|----------|-----|-------|
| 1 | `a1b2c3d4` | Add `session-tracking` maxLength guard | project | 3 sessions, sparse-note trend | 4d | — |
| 2 | `e5f6a7b8` | Nudge cooldown too short for solo dev | global | 2 sessions, friction theme | 1d | #142 |
  • Evidence: a one-line summary of the trend and session count that graduated the proposal.
  • Age: days since creation. Issue: the existing github-issue: link, else —.

Below it list proposals awaiting verification (no decision offered), deferred proposals as ` <short-id> - deferred: <condition> (deferred <date>) and stalled ones as <short-id> - stalled in work: <hint> `.


Step 4 - Collect Decisions

For each pending or stalled proposal, show the proposed change (the exact YAML it names, or the file and section it targets) and ask via AskUserQuestion:

◆ "<proposal title>" [scope: project]
Proposed change:
<exact YAML or file+section from the proposal note>
1. Accept - apply this change
2. Reject - do not adopt, record why
3. Defer - revisit later, leave in queue
4. Skip - no decision this round

For Reject or Defer take a one-line reason from the follow-up (or an "Other" free-text option) so the rationale is recorded verbatim in the adoption-decision note. Skip leaves the item untouched: no note, no transition.


Step 5 - Carry Out Dispositions

Before any Accept - ensure the proposal note

The floor schema requires the proposal note in the queue phase, and start is gate-blocked without it. A proposal created before the retrospective filled it has none, so every Accept path (project, global, maintainer or community) first checks Step 2's list. When the proposal note is absent, upsert it from the item's summary, the Step 2 scope classification and a backfill marker, before any config edit, push or `start`:

to-call
{"tool": "notes_write", "op": "upsert", "args": {"itemId": "<uuid>", "key": "proposal", "role": "queue", "body": "Problem and evidence: <from the item summary>.\nChange: <the exact change the summary names>.\nExpected effect: <as stated in the summary, or not stated>.\nBlast radius: <as stated, or not stated>.\nScope: <global | project-specific; target rootId>.\nbackfilled by review-proposals <YYYY-MM-DD>"}}

Check data.results[0].ok. Never write a note that is only a URL.

Accept - project-scoped
  1. Extract the exact YAML from the proposal note. If it has none ready to apply, draft the edit, show it as a diff against the current config file, and confirm via AskUserQuestion before applying anything.
  2. A different `rootId`. If the proposal targets a different rootId than this workspace's project.rootId, do not edit this config. Upsert adoption-decision recording that the change must be applied from the owning workspace, and treat the item as deferred (leave it in queue; do not advance).
  3. Otherwise Edit the config file to apply the change (additive and targeted, not a rewrite).
  4. Validate the full file text, LF-normalized, before pushing. Act on data.results[0].valid and data.results[0].errors (each {path, reason}); validate reports an invalid document there, it does not fail the element with config_invalid. Strict validation rejects an unknown key: a top-level retrospective: or orchestration: block fails, so move it under extensions.claude-code. Rules: `current/docs/config-reference.md`.
to-call
{"tool": "config", "op": "validate", "args": {"rootId": "<rootId>", "configYaml": "<full file text>"}}
  1. Read the head version, then push with it as expectedVersion:
to-call
{"tool": "config", "op": "get", "args": {"rootId": "<rootId>"}}
to-call
{"tool": "config", "op": "push", "args": {"rootId": "<rootId>", "configYaml": "<full file text>", "expectedVersion": "<head version from get>"}}

expectedVersion is the data.results[0].version that get returned (an integer, 1 or greater; 0 is invalid_request). When the root has no config yet, get's element fails with not_found: omit expectedVersion from the push. Then check ok and data.results[0].ok; on a failure read data.results[0].error.code. On version_conflict (error.detail {expected, actual}) never force blindly: get the head again. If its version differs from the one you sent, the head moved: diff its configYaml against the local file, show the user, and once they confirm the local file wins re-push with the new head version as expectedVersion. If it still equals what you sent, the local text matches an older version (superseded): re-push with force: true and the same expectedVersion only after the user confirms that revert. force never skips the compare-and-set. config_invalid carries error.detail.errors as {path, reason} pointers: fix and re-validate.

  1. Upsert the closure note:
to-call
{"tool": "notes_write", "op": "upsert", "args": {"itemId": "<uuid>", "key": "adoption-decision", "role": "work", "body": "accepted - <rationale>. Applied to <config file actually edited> (<section>), pushed per-root <rootId> on <YYYY-MM-DD>."}}
  1. Advance with start twice, as two sequential calls (queue to work, then work to review):
to-call
{"tool": "advance", "op": "transition", "args": {"itemId": "<uuid>", "trigger": "start"}}

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
212
Repository forks
25
7-day trend score
27

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/jpicklyk/task-orchestrator/review-proposals/badge)](https://verified-skill.com/skills/jpicklyk/task-orchestrator/review-proposals)

Something wrong with this skill or its page? Tell us.