fix(ulw-plan): recognize approval intent and stop the approval-gate loop#54
fix(ulw-plan): recognize approval intent and stop the approval-gate loop#54JSap0914 wants to merge 1 commit into
Conversation
The planner waited for one exact approval phrase before writing `.omo/plans/<slug>.md` and kept no durable record of what it was waiting on, so after context growth it re-ran exploration and re-emitted the full blocked-gate message — a token-burning loop even when the user clearly approved. Tighten the gate wording so the planner accepts common approval replies (and localized equivalents), persists the pending gate to `.omo/drafts/<slug>.md` and reads that state on the next turn instead of restating the whole plan, and emits a single concise prompt when still unapproved. The planner-only safety boundary and the `$start-work` bootstrap exception are unchanged. Extends ulw-plan-skill.test.mjs. Fixes code-yeongyu#48.
|
Thanks for the PR! Changes to LazyCodex land through oh-my-openagent — could you open this against omo-codex over there instead? PRs in this repository can't be merged. If you're working with a coding agent, prompt it like this:
|
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates the ulw-plan skill documentation and tests to make the “approval gate” more robust and less prone to looping by persisting gate state and accepting flexible approval intent.
Changes:
- Added new “recognize approval intent / persist gate / avoid looping” guidance to
SKILL.mdandfull-workflow.md. - Mirrored the same approval-gate guidance into the
components/ultraworkcopies of the docs. - Strengthened tests to assert the new guidance is present in the skill/workflow references.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| plugins/omo/test/ulw-plan-skill.test.mjs | Adds assertions to enforce new approval-gate wording in docs. |
| plugins/omo/skills/ulw-plan/references/full-workflow.md | Documents robust approval handling + durable gate state persistence. |
| plugins/omo/skills/ulw-plan/SKILL.md | Adds a compact bullet describing the new approval gate behavior. |
| plugins/omo/components/ultrawork/skills/ulw-plan/references/full-workflow.md | Mirrors the same workflow guidance for the ultrawork component. |
| plugins/omo/components/ultrawork/skills/ulw-plan/SKILL.md | Mirrors the same SKILL.md bullet for the ultrawork component. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| assert.match(skill, /Recognize approval intent/); | ||
| assert.match(skill, /do not demand one exact magic phrase/); | ||
| assert.match(skill, /record the pending gate in `\.omo\/drafts\/<slug>\.md`/); | ||
| assert.match(skill, /ask ONE concise approval question/); |
|
|
||
| Then **wait for the user's explicit okay** before generating the plan. No Metis, no plan file, no execution until the user approves. If the user amends scope, fold it in and re-present the brief. This gate replaces any automatic interview-to-plan transition. | ||
|
|
||
| Handle approval intent robustly so the gate never loops. Accept clear approval replies — "yes", "approve", "approved", "proceed", "go ahead", "do it", "write the plan", "create the plan", and localized equivalents (e.g. Korean "네", "응", "진행", "ㄱㄱ", "작성해") — as approval; never require one exact magic phrase. When you present the brief, persist the pending gate to `.omo/drafts/<slug>.md` with the exact pending action ("awaiting approval to write `.omo/plans/<slug>.md`") and target plan path; on the next turn read that durable gate state first instead of re-running exploration or re-explaining the full planning status. If the reply is still not approval, emit a single concise approval prompt rather than restating the whole brief, so the gate cannot burn context in a re-approval loop. Replies that amend scope update the brief and re-present it; they never trigger plan generation. |
|
|
||
| Then **wait for the user's explicit okay** before generating the plan. No Metis, no plan file, no execution until the user approves. If the user amends scope, fold it in and re-present the brief. This gate replaces any automatic interview-to-plan transition. | ||
|
|
||
| Handle approval intent robustly so the gate never loops. Accept clear approval replies — "yes", "approve", "approved", "proceed", "go ahead", "do it", "write the plan", "create the plan", and localized equivalents (e.g. Korean "네", "응", "진행", "ㄱㄱ", "작성해") — as approval; never require one exact magic phrase. When you present the brief, persist the pending gate to `.omo/drafts/<slug>.md` with the exact pending action ("awaiting approval to write `.omo/plans/<slug>.md`") and target plan path; on the next turn read that durable gate state first instead of re-running exploration or re-explaining the full planning status. If the reply is still not approval, emit a single concise approval prompt rather than restating the whole brief, so the gate cannot burn context in a re-approval loop. Replies that amend scope update the brief and re-present it; they never trigger plan generation. |
Fixes #48.
Problem
ulw-plan's approval gate waits for the user to reply with one exact phrase before it writes.omo/plans/<slug>.md, and it keeps no durable record of what it is waiting on. After context growth or a turn transition the planner re-runs exploration and re-emits the full "blocked at the approval gate" message — a token-burning loop, even when the user has clearly approved ("yes", "proceed", etc.).Fix
Tighten the gate wording in the
ulw-planskill and itsreferences/full-workflow.mdso the planner:.omo/drafts/<slug>.md(exact pending action + target plan path) and reads that durable state on the next turn instead of re-running exploration or restating the whole plan;The safety boundary is unchanged: still planner-only, still no plan file / Metis / execution before approval, and the narrow
$start-workbootstrap exception is preserved.Verification
Extended
plugins/omo/test/ulw-plan-skill.test.mjswith assertions for the approval-intent / durable-state / single-prompt contract:Component (
components/ultrawork/skills/ulw-plan/) and packaged (skills/ulw-plan/) copies are kept byte-identical, so the sync-skills drift check stays green.Summary by cubic
Stops the approval-gate loop in
ulw-planby recognizing approval intent and persisting gate state to.omo/drafts/<slug>.md. Fixes #48 while keeping the planner-only safety boundary and the$start-workexception unchanged..omo/plans/<slug>.md) and read it on the next turn to avoid re-running exploration.Written for commit e3c3f10. Summary will update on new commits.