From 03ce3456851ae08c5dd130eea4ec6e67276142ec Mon Sep 17 00:00:00 2001 From: toki Date: Sun, 16 Aug 2026 11:27:38 +0900 Subject: [PATCH] sync: agent-ops from agentic-framework v1.1.207 --- agent-ops/.version | 2 +- agent-ops/skills/common/code-review/SKILL.md | 77 +++++++---------- .../common/code-review/agents/openai.yaml | 4 +- agent-ops/skills/common/plan/SKILL.md | 84 +++++++------------ .../skills/common/plan/agents/openai.yaml | 4 +- .../plan/templates/review-stub-template.md | 20 +++-- .../common/prepare-epic-work-items/SKILL.md | 52 +++++++----- .../agents/openai.yaml | 6 +- .../scripts/run_epic_cycle.py | 12 +-- .../tests/test_run_epic_cycle.py | 6 ++ .../prepare-milestone-workspace/SKILL.md | 45 ++++++---- .../agents/openai.yaml | 6 +- .../scripts/prepare_workspace.py | 29 +------ .../tests/test_prepare_workspace.py | 15 ++++ agent-ops/skills/common/router.md | 3 +- 15 files changed, 168 insertions(+), 197 deletions(-) diff --git a/agent-ops/.version b/agent-ops/.version index 0f55d52..093ad47 100644 --- a/agent-ops/.version +++ b/agent-ops/.version @@ -1 +1 @@ -1.1.206 +1.1.207 diff --git a/agent-ops/skills/common/code-review/SKILL.md b/agent-ops/skills/common/code-review/SKILL.md index 6e62c2c..9bedbdb 100644 --- a/agent-ops/skills/common/code-review/SKILL.md +++ b/agent-ops/skills/common/code-review/SKILL.md @@ -1,68 +1,51 @@ --- name: code-review -description: Review the requested code or one active PLAN/CODE_REVIEW task and report concrete correctness findings without automatically creating another workflow state. +description: Review code or finalize one dispatcher PLAN/CODE_REVIEW task with the smallest required next state. --- # Code Review -## Purpose +## Review -Judge correctness, regressions, contracts, and proportionate test coverage. The review ends with findings and a verdict. It does not automatically generate a new plan, SDD review, user-review file, routing pass, completion log, or roadmap sync. +- Judge only the user request, contracts, regressions, and required tests. +- Run the smallest relevant verification. +- Use `Required` only for a concrete defect. Give evidence, impact, and one fix. +- Suggested/Nit findings never block PASS. +- Do not demand architecture, metadata, SDD, optional environments, or exhaustive tests. +- Do not add validation, approval, or state when a direct fix exists. -## Scope - -1. Use the task or files named by the user. -2. If the user refers to an active task, select the exact active `PLAN-*.md` and `CODE_REVIEW-*.md` pair. -3. If multiple active tasks match and the request does not identify one, report the paths and ask for the target. -4. Start from the diff, then inspect only callers, contracts, and tests needed to judge changed behavior. -5. Do not read unrelated archive history. - -## Review method - -- Compare the implementation with the user request and applicable public or internal contract. -- Run the smallest relevant tests when safe and available. -- Add a focused reproducer only when needed to prove a suspected defect. -- Missing copied command output or an unfilled review stub is not a code defect. -- Missing optional live/full-cycle verification is reported as residual risk, not a failed verdict. -- Do not require new validation, approval, or state as the fix when the cause can be corrected directly. - -## Findings - -Use three severities: - -- `Required`: a concrete correctness, security, data-loss, compatibility, or directly required test defect. -- `Suggested`: a useful improvement that does not block the requested result. -- `Nit`: optional cleanup. - -Every Required finding includes exact evidence, affected file/line, impact, and one concrete fix. Do not create Required findings for preferred architecture, missing process metadata, unrun optional environments, SDD divergence, or lack of exhaustive evidence. +Verification, defect analysis, and fix selection are review-agent-owned at verdict time. +Missing or incomplete implementation-recorded verification output alone is not `Required`. +Collect the evidence and select the fix here; do not delegate diagnosis or solution selection to the plan skill or implementing agent. ## Verdict - `PASS`: no Required findings. - `FAIL`: one or more Required findings. -- `WARN`: use only when the user or existing task protocol requires a middle state; Suggested findings alone may still PASS with residual suggestions. +- `WARN`: only when an existing protocol requires a non-terminal state. -Append a short result to the active review file when one exists. Otherwise report findings directly in chat. +Write exactly: -## After the verdict +```text +## Code Review Result -- `PASS`: report completion and the tests actually run. Archive task artifacts or write `complete.log` only when the user explicitly requested task-loop finalization. -- `FAIL`: report the minimal fixes. Do not automatically invoke `plan`, `finalize-task-routing`, `sync-milestone-workstate`, or `update-roadmap`. -- Ask the user directly only when a product decision or new authorization is truly required. Do not create `USER_REVIEW.md` as a stop-state unless the user explicitly asks for a file-based handoff. -- `milestone-task`, SDD Evidence Map, and `Roadmap Completion` metadata may help identify scope but are not verdict gates. +- Overall Verdict: PASS|WARN|FAIL +``` -## Optional task finalization +## Dispatcher finalization -When the user explicitly asks to finalize an active task after PASS: +A dispatcher child is an explicit task-loop finalization request. -1. Preserve the active plan and review as logs using the existing naming convention. -2. Write a concise `complete.log` from the template. -3. Move the completed task to the existing archive path without overwriting data. -4. Report exact Milestone/Task metadata if present; do not require it. +- `PASS`: archive the active pair, write `complete.log`, and move the task to `agent-task/archive/YYYY/MM/`. +- `FAIL`: archive the current pair and create one minimal follow-up PLAN/CODE_REVIEW pair through `plan`. +- Create `USER_REVIEW.md` only for a required user decision or authorization that no authorized executor can supply. +- Never create a follow-up for Suggested/Nit findings, optional verification, or process metadata. -## Quality rules +Preserve first-line `milestone-task` metadata in `complete.log`. Do not update roadmap state here. +Archive as `plan__GNN_.log` and `code_review__GNN_.log`. Never overwrite. -- Lead with findings ordered by severity. -- Cite exact files and lines. -- Keep unrelated pre-existing issues out of the verdict. -- Do not force a review loop for Suggested or Nit findings. +Outside a dispatcher task loop, report the verdict only unless the user requests file finalization. + +## Output + +Lead with Required findings. Report verdict, tests run, next state, and residual risk. diff --git a/agent-ops/skills/common/code-review/agents/openai.yaml b/agent-ops/skills/common/code-review/agents/openai.yaml index f053bc0..d56f7a4 100644 --- a/agent-ops/skills/common/code-review/agents/openai.yaml +++ b/agent-ops/skills/common/code-review/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "Code Review" - short_description: "Review and route task loops" - default_prompt: "Use $code-review to review or resolve the active task, archive it, and on WARN/FAIL either create a justified milestone-lock/external-execution USER_REVIEW stop or invoke $plan for the next routed pair." + short_description: "Review and finalize task loops" + default_prompt: "Use -review to review this change and materialize the required dispatcher next state." diff --git a/agent-ops/skills/common/plan/SKILL.md b/agent-ops/skills/common/plan/SKILL.md index 68270c5..39b45e8 100644 --- a/agent-ops/skills/common/plan/SKILL.md +++ b/agent-ops/skills/common/plan/SKILL.md @@ -1,78 +1,58 @@ --- name: plan -description: Create a concise implementation plan when the user explicitly asks for one or when a large change needs a durable execution handoff. +description: Create a minimal implementation PLAN/CODE_REVIEW pair that is directly executable by the dispatcher. --- # Plan -## Purpose +## Rules -Create the smallest plan that lets an implementer make the requested change safely. A plan is optional for ordinary implementation and is not gated by roadmap status, SDD state, preflight, review history, or evidence metadata. +- Use one plan. Split only for real file ownership or execution dependencies. +- Keep scope to the user request and required behavior. +- Do not add approval, SDD, consistency, full-test, or environment gates. +- Block only for a required user decision, security/credential risk, irreversible change, or explicit dependency. +- Fix the cause. Do not add validation or state as a workaround. -## When to use +## Dispatcher contract -- The user explicitly asks for a plan or durable handoff. -- The change is large enough that multiple files or ownership boundaries need an ordered checklist. -- A reviewer asks for one concrete follow-up plan. +Every runnable task has exactly one active pair: -Do not create a plan for a small fix that can be implemented and verified directly. +- `PLAN-{lane}-GNN.md` +- `CODE_REVIEW-{lane}-GNN.md` -## Context +Both files start with the same metadata: -1. Read the user request and only the relevant project/domain rules. -2. Inspect the files and tests directly related to the change. Full-file reads are not mandatory when a focused range is sufficient. -3. If a matching active Milestone exists, use its goal, scope, Tasks, and plain decision notes as context. -4. Treat an SDD as an optional design reference. Its status and evidence tables do not block planning. -5. Read archive evidence only when an active task points to an exact file needed for a follow-up. +```text + +``` -## Decisions and blockers +Add `milestone-task=` only for an exact `m-` task. -- Infer normal technical details from current code and conventions. -- If one user-owned product decision is directly required, ask for that decision and continue all independent planning work. -- Fix the cause in the existing design. Do not plan new validation, approval, or state as a workaround. +The PLAN must contain: -## Task shape +- `## Goal` +- `## Implementation Checklist` +- exactly one `## Modified Files Summary` +- `## Verification` -- Prefer one plan. -- Split only when children can be implemented and verified independently or when the user asks for parallel tasks. -- Preserve existing `agent-task//` naming when continuing an active task. -- Existing routed filenames such as `PLAN-local-GNN.md` remain valid. Choose the smallest existing grade convention needed by repository tooling; do not run a separate routing workflow unless the user requests routing. -- `milestone-task` metadata is optional target information, not a completion contract. +`Modified Files Summary` is a table. Its first column contains exact backtick workspace file paths. Do not use directories, globs, placeholders, alternatives, or prose claims. -## Required plan content +Render the review file from `templates/review-stub-template.md`. Copy the implementation checklist into `{implementation_checklist}`. The final item must require filling implementation-owned review evidence. -- Goal and concise background. -- Files or components expected to change. -- Ordered implementation checklist. -- Product decisions already made and any one directly required open decision. -- Minimal verification proportional to the change. -- Explicit dependencies only when they are real execution dependencies. +Validate before handoff: -Do not require: - -- exhaustive files-read inventories; -- before/after snippets for every edit; -- SDD approval or Evidence Map reconstruction; -- external environment preflight for optional verification; -- a mandatory review stub evidence form; -- routing scores, loop-risk analysis, or capability-grade justification. - -## Review reference - -When the existing task loop expects a review file, create one `CODE_REVIEW--GNN.md` beside the plan from the simple review template. It is a convenience for a later explicit review, not an implementation completion gate. The implementer may add notes, but blank evidence fields do not invalidate completed code. +```bash +python3 agent-ops/skills/common/orchestrate-agent-task-loop/scripts/dispatch.py \ + --workspace \ + --validate-plan +``` ## Follow-up -- A WARN/FAIL review may be fixed directly or receive one concise follow-up plan. -- Do not automatically create another plan, reroute the task, generate `USER_REVIEW.md`, or restart a loop. -- Preserve useful findings; discard obsolete process metadata. +For dispatcher WARN/FAIL follow-up, treat the reviewer's closed finding packet as the decision authority. The new plan contains no worker-owned diagnosis or solution choice. Include only concrete Required fixes and their smallest acceptance commands. -## Validation - -- The plan matches the user request and does not expand scope. -- Referenced files and commands exist. -- Verification is the smallest relevant test set. +Do not create a follow-up for Suggested/Nit findings, optional verification, metadata cleanup, or speculative hardening. ## Output -Report the plan path, scope, key files, minimal verification, and any directly required decision or explicit dependency. +Report the pair paths, exact write set, verification commands, and real blocker if one exists. diff --git a/agent-ops/skills/common/plan/agents/openai.yaml b/agent-ops/skills/common/plan/agents/openai.yaml index 47caced..e384cbc 100644 --- a/agent-ops/skills/common/plan/agents/openai.yaml +++ b/agent-ops/skills/common/plan/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "Plan" - short_description: "Write implementation plans" - default_prompt: "Use $plan to analyze this repository change, collect current routing evidence, run $finalize-task-routing with local-first capability-gap policy, and create the routed PLAN/CODE_REVIEW pair." + short_description: "Create dispatcher-ready task pairs" + default_prompt: "Use to create the smallest dispatcher-valid PLAN/CODE_REVIEW pair for this change." diff --git a/agent-ops/skills/common/plan/templates/review-stub-template.md b/agent-ops/skills/common/plan/templates/review-stub-template.md index a83eda1..28cf740 100644 --- a/agent-ops/skills/common/plan/templates/review-stub-template.md +++ b/agent-ops/skills/common/plan/templates/review-stub-template.md @@ -6,23 +6,25 @@ -## Changed Areas +## Implementation Checklist -- +{implementation_checklist} ## Implementation Notes - 없음 -## Verification Run +## Verification Results - 없음 -## Review Result +## Deviations -- Verdict: pending -- Required findings: 없음 -- Suggested findings: 없음 -- Residual risk: 없음 +- 없음 -This file is a review aid. Filling every field, archiving it, or producing additional metadata is not required for the implementation itself to be complete. +## Review-Only Checklist + +- [ ] Run applicable required verification and record fresh command/output. +- [ ] Record Required findings with evidence, root cause, and one selected fix. +- [ ] Append exactly one `## Code Review Result` verdict. +- [ ] Materialize the dispatcher next state. diff --git a/agent-ops/skills/common/prepare-epic-work-items/SKILL.md b/agent-ops/skills/common/prepare-epic-work-items/SKILL.md index 35c79dd..d26112a 100644 --- a/agent-ops/skills/common/prepare-epic-work-items/SKILL.md +++ b/agent-ops/skills/common/prepare-epic-work-items/SKILL.md @@ -1,37 +1,43 @@ --- name: prepare-epic-work-items -description: Prepare one Epic by implementing small tasks directly and creating concise plans only for genuinely large tasks. +description: Materialize one exact Epic into direct work and dispatcher-valid PLAN/CODE_REVIEW pairs through the bundled runtime. --- # Prepare Epic Work Items -## Purpose +## Run -Turn one Epic into executable work with **verification gate minimization**. Small tasks are implemented directly; large tasks receive one concise plan. Repeated review, refinement, routing, commit, push, or dispatcher barriers are not automatic. +Use the bundled runtime. Do not reproduce its state machine manually. -## Procedure +```bash +python3 agent-ops/skills/common/prepare-epic-work-items/scripts/run_epic_cycle.py \ + --workspace \ + --milestone \ + --epic +``` -1. Resolve one exact Milestone and Epic. -2. Classify each Task: - - direct work when it is local, bounded, and safe; - - plan work when it spans meaningful ownership or contract boundaries. -3. Implement direct work and run the smallest related test. -4. Create at most one plan per coherent large change unless independent parallel work clearly benefits from a split. -5. Report prepared and completed Task ids. +Supply `AGENT_TASK_EXECUTION_CATALOG` and `AGENT_TASK_PLANNER_TARGET`, or their CLI flags. They select executors; they are not approval gates. + +The runtime must: + +1. resolve one exact Epic; +2. implement bounded small work directly; +3. create the smallest dispatcher-valid pair for remaining large work; +4. preserve exact `milestone-task` ids and write claims; +5. reject scope expansion and forbidden finalization artifacts; +6. emit `EPIC_COMPLETED` or `EPIC_WORK_ITEMS_READY`. + +## No extra gates + +- Use the smallest related test. +- Do not add SDD, consistency, full-suite, environment, approval, or evidence gates. +- Do not split unless file ownership or execution dependency requires it. +- Do not create USER_REVIEW for repository-fixable work. ## Real blockers -- a directly required product decision; -- security or credential authorization; -- data-loss or irreversible external change risk; -- an explicit user-created dependency; -- dirty-worktree or branch mutation risk. +Only a required user decision, security/credential authorization, irreversible change, explicit dependency, or dirty-worktree risk blocks work. -Milestone state, SDD status, implementation-lock metadata, consistency preflight, review files, routing grade, evidence formatting, commit/push, and optional environment validation are not blockers. +## Output -## Prohibited - -- Do not run automatic initial review → refine → final review loops. -- Do not create USER_REVIEW stop artifacts unless the user explicitly requests a file handoff. -- Do not auto-start a dispatcher, commit, or push unless requested. -- Do not expand beyond the selected Epic. +Report Epic id, direct work, active pairs, terminal event, and real blocker. diff --git a/agent-ops/skills/common/prepare-epic-work-items/agents/openai.yaml b/agent-ops/skills/common/prepare-epic-work-items/agents/openai.yaml index 073c5f7..bd049de 100644 --- a/agent-ops/skills/common/prepare-epic-work-items/agents/openai.yaml +++ b/agent-ops/skills/common/prepare-epic-work-items/agents/openai.yaml @@ -1,4 +1,4 @@ interface: - display_name: "Prepare Epic Work Items" - short_description: "Turn one Epic into reviewed work and plans" - default_prompt: "Use $prepare-epic-work-items to complete small work and prepare reviewed plans for one Epic." + display_name: "Prepare Epic Work" + short_description: "Materialize one Epic into runnable work" + default_prompt: "Use -epic-work-items to materialize this Epic into direct work and dispatcher-valid task pairs." diff --git a/agent-ops/skills/common/prepare-epic-work-items/scripts/run_epic_cycle.py b/agent-ops/skills/common/prepare-epic-work-items/scripts/run_epic_cycle.py index 2f1fe1e..19fcf90 100755 --- a/agent-ops/skills/common/prepare-epic-work-items/scripts/run_epic_cycle.py +++ b/agent-ops/skills/common/prepare-epic-work-items/scripts/run_epic_cycle.py @@ -124,16 +124,8 @@ def section(text: str, heading: str) -> str: def verify_milestone_gate(text: str) -> None: - status_body = section(text, "상태") - status_match = re.search(r"^\[(.+?)\]\s*$", status_body, re.MULTILINE) - status = status_match.group(1).strip() if status_match else "" - if status not in {"계획", "진행중"}: - raise CycleError(f"milestone must be [계획] or [진행중]: actual={status or 'missing'}") - lock = section(text, "구현 잠금") - if not re.search(r"^- 상태:\s*해제\s*$", lock, re.MULTILINE): - raise CycleError("milestone implementation lock is not 해제") - if not re.search(r"^- 결정 필요:\s*없음\s*$", lock, re.MULTILINE): - raise CycleError("milestone has unresolved 결정 필요") + # Status and legacy lock metadata are context, not execution gates. + return None def parse_epics(text: str) -> list[Epic]: diff --git a/agent-ops/skills/common/prepare-epic-work-items/tests/test_run_epic_cycle.py b/agent-ops/skills/common/prepare-epic-work-items/tests/test_run_epic_cycle.py index 5676c70..9ef990d 100644 --- a/agent-ops/skills/common/prepare-epic-work-items/tests/test_run_epic_cycle.py +++ b/agent-ops/skills/common/prepare-epic-work-items/tests/test_run_epic_cycle.py @@ -33,6 +33,12 @@ def command(cwd: Path, *args: str) -> str: class EpicCycleContractTest(unittest.TestCase): + def test_status_and_legacy_lock_do_not_gate_epic_work(self) -> None: + MODULE.verify_milestone_gate( + "## 상태\n\n[완료]\n\n" + "## 구현 잠금\n\n- 상태: 잠김\n- 결정 필요: 선택\n" + ) + def test_cycle_requires_runtime_catalog_and_defaults_review_target(self) -> None: args = MODULE.parser().parse_args( [ diff --git a/agent-ops/skills/common/prepare-milestone-workspace/SKILL.md b/agent-ops/skills/common/prepare-milestone-workspace/SKILL.md index b98e64b..b466aec 100644 --- a/agent-ops/skills/common/prepare-milestone-workspace/SKILL.md +++ b/agent-ops/skills/common/prepare-milestone-workspace/SKILL.md @@ -1,33 +1,46 @@ --- name: prepare-milestone-workspace -description: Prepare a requested Milestone branch or worktree and selected Epic work with only Git data-safety checks. +description: Prepare one exact Milestone workspace and selected Epic batch through the bundled deterministic runtime. --- # Prepare Milestone Workspace -## Purpose +## Run -Prepare the requested workspace and work items without roadmap readiness gates. The only blocking checks are those needed to avoid overwriting user changes, branch collisions, credential/security issues, or an explicit user-stated dependency. +Use the bundled runtime. Do not recreate its branch, batch, claim, or recovery logic in prose. -## Procedure +```bash +python3 agent-ops/skills/common/prepare-milestone-workspace/scripts/prepare_workspace.py \ + --repo \ + --milestone \ + --workspace \ + --epics +``` -1. Resolve one exact active Milestone and requested workspace. -2. Refuse destructive branch/worktree mutation when the checkout is dirty, the target path is owned by another worktree, or the branch target is ambiguous. -3. Create or reuse `feature/` according to the repository's existing Git Flow setup. -4. Select the requested Epic range and call `prepare-epic-work-items` only for those Epics. -5. Start a dispatcher only when the user requested execution and prepared runnable work exists. +For the current workspace, add `--existing-workspace`. +Supply `AGENT_TASK_EXECUTION_CATALOG` and `AGENT_TASK_PLANNER_TARGET`, or their CLI flags. They select executors; they are not approval gates. -## Non-gates +Selectors are `remaining`, `first-incomplete`, exact Epic ids, or an inclusive `N..M` range. -- Milestone state, former implementation-lock fields, SDD status, consistency checks, plan routing grade, review history, push state, and full validation matrices do not block preparation. -- An open product decision pauses only the selected Epic work that needs it. -- A missing optional execution target or live environment is reported; it does not invalidate already prepared independent work. +The runtime must: + +1. resolve one exact Milestone and workspace; +2. protect dirty work, branch ownership, and upstream integrity; +3. create or reuse `feature/`; +4. prepare every selected Epic; +5. emit `MILESTONE_WORK_ITEMS_READY` only after deterministic pair validation; +6. run dispatcher dry-run before one live dispatcher when runnable plans exist. + +## No extra gates + +- Milestone status, implementation-lock metadata, SDD, consistency, review history, and optional environments do not block preparation. +- Do not add approval or validation stages outside the bundled runtime. +- Pause only the Epic that needs a real user decision, authorization, or explicit dependency. ## Safety -- Never force-push, overwrite dirty work, delete branches/worktrees automatically, or expose credentials. -- Preserve any partially created branch/worktree and report the exact recovery condition after a failure. +Never force-push, overwrite dirty work, or delete branches/worktrees on failure. Report the exact recovery command. ## Output -Report Milestone, branch, workspace, selected Epics, prepared work, execution started or not started, and any real safety blocker. +Report workspace, branch, selected Epics, terminal event, dispatcher state, and real blocker. diff --git a/agent-ops/skills/common/prepare-milestone-workspace/agents/openai.yaml b/agent-ops/skills/common/prepare-milestone-workspace/agents/openai.yaml index bde6be4..dd3675c 100644 --- a/agent-ops/skills/common/prepare-milestone-workspace/agents/openai.yaml +++ b/agent-ops/skills/common/prepare-milestone-workspace/agents/openai.yaml @@ -1,4 +1,4 @@ interface: - display_name: "Start Milestone Epic Work" - short_description: "Prepare selected Milestone Epics and run dispatcher" - default_prompt: "Use $prepare-milestone-workspace to start the selected Epic range for the current Milestone workspace and run its dispatcher." + display_name: "Prepare Milestone Work" + short_description: "Prepare and run selected Milestone Epics" + default_prompt: "Use -milestone-workspace to prepare the selected Milestone Epics with the bundled runtime." diff --git a/agent-ops/skills/common/prepare-milestone-workspace/scripts/prepare_workspace.py b/agent-ops/skills/common/prepare-milestone-workspace/scripts/prepare_workspace.py index 9c64f30..de06b44 100755 --- a/agent-ops/skills/common/prepare-milestone-workspace/scripts/prepare_workspace.py +++ b/agent-ops/skills/common/prepare-milestone-workspace/scripts/prepare_workspace.py @@ -110,15 +110,6 @@ def milestone_contract(path: Path) -> dict[str, str]: status_body = section(text, "상태") status_match = re.search(r"^\[(.+?)\]\s*$", status_body, re.MULTILINE) status = status_match.group(1).strip() if status_match else "" - lock = section(text, "구현 잠금") - lock_state = re.search(r"^- 상태:\s*(.+?)\s*$", lock, re.MULTILINE) - decision = re.search(r"^- 결정 필요:\s*(.+?)\s*$", lock, re.MULTILINE) - if status != "계획": - raise PreparationError(f"milestone must be [계획]: actual={status or 'missing'}") - if not lock_state or lock_state.group(1).strip() != "해제": - raise PreparationError("milestone implementation lock is not 해제") - if not decision or decision.group(1).strip() != "없음": - raise PreparationError("milestone has unresolved 결정 필요") return { "title": first_heading(text, "# Milestone:"), "status": status, @@ -126,25 +117,7 @@ def milestone_contract(path: Path) -> dict[str, str]: def existing_milestone_contract(path: Path) -> dict[str, str]: - text = path.read_text(encoding="utf-8") - status_body = section(text, "상태") - status_match = re.search(r"^\[(.+?)\]\s*$", status_body, re.MULTILINE) - status = status_match.group(1).strip() if status_match else "" - lock = section(text, "구현 잠금") - lock_state = re.search(r"^- 상태:\s*(.+?)\s*$", lock, re.MULTILINE) - decision = re.search(r"^- 결정 필요:\s*(.+?)\s*$", lock, re.MULTILINE) - if status not in {"계획", "진행중"}: - raise PreparationError( - f"Milestone work requires [계획] or [진행중]: actual={status or 'missing'}" - ) - if not lock_state or lock_state.group(1).strip() != "해제": - raise PreparationError("milestone implementation lock is not 해제") - if not decision or decision.group(1).strip() != "없음": - raise PreparationError("milestone has unresolved 결정 필요") - return { - "title": first_heading(text, "# Milestone:"), - "status": status, - } + return milestone_contract(path) def parse_epics(text: str) -> list[Epic]: diff --git a/agent-ops/skills/common/prepare-milestone-workspace/tests/test_prepare_workspace.py b/agent-ops/skills/common/prepare-milestone-workspace/tests/test_prepare_workspace.py index c013177..a582714 100644 --- a/agent-ops/skills/common/prepare-milestone-workspace/tests/test_prepare_workspace.py +++ b/agent-ops/skills/common/prepare-milestone-workspace/tests/test_prepare_workspace.py @@ -51,6 +51,21 @@ class PrepareWorkspaceTest(unittest.TestCase): Path("/tmp/example/sample-feature-worktree"), ) + def test_status_and_legacy_lock_do_not_gate_preparation(self) -> None: + with tempfile.TemporaryDirectory() as raw: + milestone = Path(raw) / "milestone.md" + milestone.write_text( + "# Milestone: Sample\n\n" + "## 상태\n\n[완료]\n\n" + "## 구현 잠금\n\n- 상태: 잠김\n- 결정 필요: 선택\n", + encoding="utf-8", + ) + + self.assertEqual(MODULE.milestone_contract(milestone)["title"], "Sample") + self.assertEqual( + MODULE.existing_milestone_contract(milestone)["status"], "완료" + ) + def test_dispatcher_uses_common_runtime_only(self) -> None: with tempfile.TemporaryDirectory() as raw: workspace = Path(raw) diff --git a/agent-ops/skills/common/router.md b/agent-ops/skills/common/router.md index ff93c62..fa08dfd 100644 --- a/agent-ops/skills/common/router.md +++ b/agent-ops/skills/common/router.md @@ -52,5 +52,6 @@ 세부 라우팅: - workspace와 Milestone 준비를 함께 요청하면 `prepare-milestone-workspace`, 한 Epic의 작업 분류를 요청하면 `prepare-epic-work-items`를 선택한다. +- `prepare-milestone-workspace`와 `prepare-epic-work-items`는 각 SKILL.md에 지정된 번들 runtime을 직접 실행한다. 별도 승인·SDD·정합성 gate를 앞에 붙이지 않는다. - 기존 plan 분할만 요청하면 `refine-plans`, 새 plan 작성이나 재작성은 `plan`, routing 판단만 요청하면 `finalize-task-routing`을 선택한다. -- 코드 리뷰 요청은 `code-review`를 선택한다. WARN/FAIL 결과가 나와도 후속 plan이나 routing은 자동 호출하지 않고 결과와 최소 수정 사항만 보고한다. +- 코드 리뷰 요청은 `code-review`를 선택한다. 일반 리뷰는 결과만 보고한다. dispatcher child는 PASS 완료 상태 또는 Required 결함의 최소 follow-up을 반드시 materialize한다.