merge: sync orchestration before queue 00001KTVJFT6F
This commit is contained in:
commit
75d7470923
|
|
@ -1 +1,2 @@
|
|||
{"id":"orch-plan-20260612-091119-1","ticket_id":"00001KTVPS6K3","kind":"waiting_capacity_note","note":"Workspace Panel Queue notification was received, but this Orchestrator cannot safely accept implementation yet. The Orchestrator Ticket backend still reads the Ticket as `ready`, while the root workspace has unsynced/uncommitted queued Ticket changes for `00001KTVPS6K3`; root workspace is dirty (`.yoi/tickets/00001KTVPS6K3/*` plus `crates/tui/src/multi_pod.rs`). Current active work `00001KTWPE3KQ` is also in review and is specifically fixing the Panel Queue durable handoff/sync path. Re-route this Ticket after the Queue handoff is safely synced/committed and active review/merge state is clear.","author":"orchestrator","at":"2026-06-12T09:11:19Z"}
|
||||
{"id":"orch-plan-20260612-123134-2","ticket_id":"00001KTVPS6K3","kind":"accepted_plan","accepted_plan":{"summary":"Ticket role launch の first-run user message を Submit-only の短い入力へ縮小し、role behavior は builtin Profile instruction、procedural guidance は Workflow へ分離する。実装は `crates/client/src/ticket_role.rs`、`resources/profiles/{intake,orchestrator,coder,reviewer}.lua`、`resources/prompts/ticket_role/*.md`、必要な workflow/prompt resource と focused tests を対象にする。","branch":"ticket/shorten-ticket-role-launch-input","worktree":"/home/hare/Projects/yoi/.worktree/shorten-ticket-role-launch-input","role_plan":"Coder は child worktree に限定して implementation と tests/validation を行う。Reviewer は read-only で、Instruction / Workflow / Submit / control-plane 境界、prompt-context 永続性、workspace/cwd/topology 情報の分離、既存 Ticket role launch/Panel launch/workflow invocation の互換性を確認する。"},"author":"orchestrator","at":"2026-06-12T12:31:34Z"}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: 'Ticket role launch inputを短縮し、role behaviorをInstruction/Workflowへ分離する'
|
||||
state: 'queued'
|
||||
state: 'closed'
|
||||
created_at: '2026-06-11T16:03:28Z'
|
||||
updated_at: '2026-06-12T12:29:10Z'
|
||||
updated_at: '2026-06-12T13:08:52Z'
|
||||
assignee: null
|
||||
risk_flags: ['prompt-context', 'workflow-boundary', 'role-launch']
|
||||
queued_by: 'workspace-panel'
|
||||
|
|
|
|||
32
.yoi/tickets/00001KTVPS6K3/resolution.md
Normal file
32
.yoi/tickets/00001KTVPS6K3/resolution.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
Ticket role launch の first-run user message を短縮し、role behavior / procedural guidance / control-plane metadata の所管を分離した。
|
||||
|
||||
実装概要:
|
||||
- `crates/client/src/ticket_role.rs` の launch Submit text を短縮し、対象 Ticket / action instruction / per-launch context に限定した。
|
||||
- `Profile selector`、`Workflow`、`Configured launch_prompt ref`、Ticket record language guidance、runtime workspace/cwd などの control-plane / environment 情報を first-run user text から外した。
|
||||
- builtin role Profiles に `worker.instruction = "$yoi/role/<role>"` を設定し、role behavior を `resources/prompts/role/{intake,orchestrator,coder,reviewer}.md` へ移した。
|
||||
- procedural guidance は Workflow resources 側に保持・移動した。
|
||||
- obsolete な `resources/prompts/ticket_role/*.md` fragments を削除した。
|
||||
- boundary を検証する focused unit tests を追加・更新した。
|
||||
|
||||
Review / integration:
|
||||
- Implementation commit: `949531a0 client: shorten ticket role launch input`
|
||||
- Reviewer: `yoi-reviewer-role-launch-input` が approve。
|
||||
- Orchestrator merge commit: `bdbd955b merge: ticket role launch input split`
|
||||
- Ticket completion commit: `9ad5ed6d ticket: mark role launch done`
|
||||
|
||||
Validation:
|
||||
- `cargo test -p client ticket_role --lib`: pass
|
||||
- `cargo test -p manifest builtin_role_profiles_are_registered_and_resolve --lib`: pass
|
||||
- `cargo test -p pod builtin_ticket_role_instructions_resolve --lib`: pass
|
||||
- `cargo fmt --check`: pass
|
||||
- `git diff --check HEAD~1..HEAD`: pass
|
||||
- `nix build .#yoi`: pass
|
||||
- `./result/bin/yoi ticket doctor`: `doctor: ok`
|
||||
|
||||
Cleanup:
|
||||
- coder/reviewer Pods stopped。
|
||||
- child worktree `/home/hare/Projects/yoi/.worktree/shorten-ticket-role-launch-input` removed。
|
||||
- branch `ticket/shorten-ticket-role-launch-input` deleted。
|
||||
|
||||
Non-blocking follow-up:
|
||||
- 旧 `.yoi/prompts/ticket_role/*` override は launch Submit text には効かなくなるため、外部ユーザー向けには role behavior は Profile instruction、手順は Workflow override へ移す旨を必要に応じて案内すると安全。
|
||||
|
|
@ -56,4 +56,319 @@ Escalate if:
|
|||
Ticket を `workspace-panel` が queued にしました。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: decision author: orchestrator at: 2026-06-12T12:32:06Z -->
|
||||
|
||||
## Decision
|
||||
|
||||
Routing decision: implementation_ready
|
||||
|
||||
Reason:
|
||||
- Ticket body は Ticket role launch の first-run user message から role behavior / procedural guidance / control-plane metadata を外し、Submit に対象 Ticket / action instruction / per-launch context だけを残す方針を明確に記録している。
|
||||
- Instruction / Workflow / Submit / control-plane の境界、Ticket config schema に instruction field を追加しないこと、launch context template 化を避けることが binding decision として記録済みである。
|
||||
- `ready -> queued` は workspace-panel により再実行され、現在の Orchestrator backend でも `queued` として読める。relation blocker はない。
|
||||
- 以前の blocker だった Panel Queue durable handoff work `00001KTWPE3KQ` は closed 済みで、現在の orchestration worktree は clean。残る不確実性は既存 prompt/profile/workflow resource と `crates/client/src/ticket_role.rs` 周辺の bounded implementation investigation に閉じている。
|
||||
|
||||
Evidence checked:
|
||||
- Ticket body / thread / artifacts: `item.md`、`thread.md`、既存 waiting-capacity note を確認。
|
||||
- TicketRelationQuery: outgoing/incoming relation なし、blocker なし。
|
||||
- TicketOrchestrationPlanQuery: 既存 `waiting_capacity_note` と、今回の accepted plan `orch-plan-20260612-123134-2` を確認。
|
||||
- Related Ticket: `00001KTWPE3KQ` は closed 済みで、Queue handoff blocker は解消済み。
|
||||
- Workspace state: Orchestrator worktree `orchestration/yoi-orchestrator` は clean。
|
||||
- Code/resource map: `crates/client/src/ticket_role.rs`, `resources/profiles/orchestrator.lua`, `resources/prompts/ticket_role/*.md` と関連 prompt/profile/workflow resource を確認。
|
||||
- Durable context: prompt prose は resources/prompts へ集約し、Profile/Workflow が role behavior/procedure を所有する既存方針に一致する。
|
||||
- Visible Pods: active child Pod なし。
|
||||
|
||||
IntentPacket:
|
||||
|
||||
Intent:
|
||||
- Ticket role Pod launch の初回 user message を短縮し、model-visible な launch input を Submit-only の per-launch context に近づける。
|
||||
- role behavior は builtin role Profile が選ぶ Instruction、procedural guidance は Workflow、control-plane metadata は launch plan/diagnostics/trace に分離する。
|
||||
|
||||
Binding decisions / invariants:
|
||||
- `Profile selector`、`Workflow`、`Configured launch_prompt ref` などの control-plane metadata は first-run user message に含めない。
|
||||
- role behavior / 恒常的環境情報 / language / workspace_root / cwd は Instruction/system 側の責務とする。ただし今回の Git/worktree 操作対象として必要な path は Submit に明示してよい。
|
||||
- procedural guidance は Workflow 側に置く。
|
||||
- Submit に残す情報は対象 Ticket、action instruction、今回の操作対象として必要な per-launch context に限定する。
|
||||
- Ticket config に role-level `system_instruction` / `instruction` field を追加しない。
|
||||
- launch context の過剰なテンプレート化は行わず、Rust 側の短い Submit 組み立てに留める。
|
||||
- 新しい input を hidden context として差し込まず、必要な model-visible context は適切な Instruction/Workflow/committed user task/history 経由にする。
|
||||
|
||||
Requirements / acceptance criteria:
|
||||
- Ticket role launch の first-run `Segment::Text` が短くなり、対象 Ticket / action instruction / per-launch context だけを含む。
|
||||
- role behavior は builtin role instruction prompt から供給される。
|
||||
- procedural guidance は Workflow に残る、または Workflow に移されている。
|
||||
- control-plane metadata は prompt text ではなく launch plan / diagnostics / trace に留まる。
|
||||
- Ticket record language guidance は first-run user message ではなく Instruction 側の環境情報として扱われる。
|
||||
- Orchestrator launch で必要な workspace/cwd/topology 情報は Pod 環境情報と per-operation Submit 情報に分離され、Git/worktree 操作対象として必要なものだけ Submit 内で明示される。
|
||||
- 関連 unit tests が新しい出力方針を検証する。
|
||||
- `nix build .#yoi` が通る。
|
||||
|
||||
Implementation latitude:
|
||||
- builtin role instruction prompt のファイル名・配置は既存 prompt resource conventions に合わせて選んでよい。
|
||||
- `resources/prompts/ticket_role` の既存 fragment は、不要なら削除または縮小してよい。
|
||||
- `TicketRoleLaunchContext.user_instruction` rename は、変更量が大きい場合は段階的移行でもよい。ただし model-visible label は `User/action instruction` より正確な名前にする。
|
||||
- Workflow 側に移す文言は public builtin workflow と workspace dogfood workflow の責務差を保つ。
|
||||
|
||||
Escalate if:
|
||||
- Instruction / Workflow / Submit の境界に収まらない新しい model-visible 情報が見つかる。
|
||||
- Ticket role launch の dynamic data を Instruction minijinja context に入れる必要が出る。
|
||||
- Ticket config schema に新しい instruction field を追加する必要が出る。
|
||||
- Workflow invocation、workspace/user prompt override、Ticket role launch、Panel Intake / Orchestrator launch のいずれかを壊さないと実現できない。
|
||||
|
||||
Validation:
|
||||
- Ticket role launch prompt 出力の unit tests。
|
||||
- builtin role Profile が instruction prompt を解決できることの focused validation。
|
||||
- relevant cargo tests。
|
||||
- `cargo fmt --check`。
|
||||
- `git diff --check`。
|
||||
- `target/debug/yoi ticket doctor` または built binary の `yoi ticket doctor`。
|
||||
- `nix build .#yoi`。
|
||||
|
||||
Current code map:
|
||||
- 主対象: `crates/client/src/ticket_role.rs`。
|
||||
- Profile/resource: `resources/profiles/{intake,orchestrator,coder,reviewer}.lua`, `resources/prompts/ticket_role/*.md`, 必要な `resources/workflows/*` / `.yoi/workflow/*`。
|
||||
- Prompt/system integration check: `crates/pod/src/prompt/system.rs`。
|
||||
- Implementation worktree では Orchestrator/main `.yoi` records、`.yoi/memory`、local/runtime/log/lock/secret-like `.yoi` paths を生成・編集しない。
|
||||
|
||||
Critical risks / reviewer focus:
|
||||
- control-plane metadata が first-run user message に残っていないこと。
|
||||
- role behavior / procedure が Submit に残留せず、Instruction / Workflow の適切な boundary に移っていること。
|
||||
- Ticket record language guidance と workspace/cwd/topology 情報が hidden/ephemeral context injection になっていないこと。
|
||||
- Dynamic Ticket data を system Instruction 側へ混ぜないこと。
|
||||
- 既存 Ticket role launch、Panel Intake/Orchestrator launch、workflow invocation、prompt override の動作を壊していないこと。
|
||||
|
||||
Next action:
|
||||
- `queued -> inprogress` を記録してから、branch `ticket/shorten-ticket-role-launch-input` / worktree `/home/hare/Projects/yoi/.worktree/shorten-ticket-role-launch-input` を作成し、sibling coder に narrow write scope で実装を委譲する。Reviewer は coder evidence 後に read-only で起動する。
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: orchestrator at: 2026-06-12T12:32:11Z from: queued to: inprogress reason: orchestrator_acceptance field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Routing accepted for implementation. Ticket body/thread, relation blockers, orchestration plan, prior waiting-capacity note, closed Queue-handoff dependency, current Orchestrator workspace state, relevant prompt/profile/workflow code map, and visible Pods were rechecked. No unresolved blocker or missing planning decision remains. Implementation side effects will start only after this accepted `queued -> inprogress` transition is recorded, using accepted plan `orch-plan-20260612-123134-2`.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: plan author: orchestrator at: 2026-06-12T12:32:36Z -->
|
||||
|
||||
## Plan
|
||||
|
||||
Implementation worktree created for multi-agent handoff.
|
||||
|
||||
- Ticket: `00001KTVPS6K3`
|
||||
- Branch: `ticket/shorten-ticket-role-launch-input`
|
||||
- Worktree: `/home/hare/Projects/yoi/.worktree/shorten-ticket-role-launch-input`
|
||||
- Base: Orchestrator workspace HEAD `ae66c447` (`orchestration/yoi-orchestrator`), including the accepted routing record and `queued -> inprogress` transition.
|
||||
- Scope rule: implementation work happens only in this child worktree. Root/original workspace must not be read, written, validated, merged, cleaned, or used for git operations.
|
||||
- Next: spawn sibling coder with narrow write scope to the implementation worktree. Reviewer will be started after coder evidence is available.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: implementation_report author: orchestrator at: 2026-06-12T12:33:47Z -->
|
||||
|
||||
## Implementation report
|
||||
|
||||
Coder spawn initial attempt failed before socket creation.
|
||||
|
||||
- Coder Pod name: `yoi-coder-role-launch-input`
|
||||
- Error: `cwd is not readable under the configured scope: /home/hare/Projects/yoi`
|
||||
- Recovery: retry with the same child worktree write scope plus minimal non-recursive read authority on the runtime workspace root required by spawn validation. The coder task still explicitly prohibits reading/writing/validating/merging/cleaning/running git in the root/original workspace and must operate from the child worktree only.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: plan author: orchestrator at: 2026-06-12T12:34:21Z -->
|
||||
|
||||
## Plan
|
||||
|
||||
Coder delegated.
|
||||
|
||||
- Coder Pod: `yoi-coder-role-launch-input`
|
||||
- Worktree: `/home/hare/Projects/yoi/.worktree/shorten-ticket-role-launch-input`
|
||||
- Branch: `ticket/shorten-ticket-role-launch-input`
|
||||
- Scope: write `/home/hare/Projects/yoi/.worktree/shorten-ticket-role-launch-input`; read child worktree plus minimal non-recursive runtime-root read required by spawn validation.
|
||||
- Task: shorten Ticket role launch first-run Submit input, move/keep role behavior in builtin Profile instruction, keep procedural guidance in Workflow, keep control-plane metadata out of first-run user text, add focused tests, validate with relevant cargo tests and `nix build .#yoi`.
|
||||
- Constraint: coder was instructed not to use root/original workspace for decision evidence or git/validation/cleanup, and not to create generated memory/local/runtime/log/lock/secret-like `.yoi` paths.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: implementation_report author: orchestrator at: 2026-06-12T12:56:48Z -->
|
||||
|
||||
## Implementation report
|
||||
|
||||
Coder completed implementation.
|
||||
|
||||
Coder Pod:
|
||||
- `yoi-coder-role-launch-input`
|
||||
|
||||
Implementation branch/worktree:
|
||||
- Branch: `ticket/shorten-ticket-role-launch-input`
|
||||
- Worktree: `/home/hare/Projects/yoi/.worktree/shorten-ticket-role-launch-input`
|
||||
- Commit: `949531a0 client: shorten ticket role launch input`
|
||||
- Worktree status: clean
|
||||
|
||||
Changed surfaces:
|
||||
- `crates/client/src/ticket_role.rs`
|
||||
- `crates/manifest/src/profile.rs`
|
||||
- `crates/pod/src/prompt/loader.rs`
|
||||
- `resources/profiles/{intake,orchestrator,coder,reviewer}.lua`
|
||||
- `resources/prompts/role/{intake,orchestrator,coder,reviewer}.md`
|
||||
- removed obsolete `resources/prompts/ticket_role/*.md`
|
||||
- `resources/workflows/{multi-agent-workflow,ticket-intake-workflow,ticket-orchestrator-routing}.md`
|
||||
|
||||
Orchestrator-verified evidence from child worktree:
|
||||
- `git status --short --branch` clean on `ticket/shorten-ticket-role-launch-input`
|
||||
- `cargo test -p client ticket_role --lib`: pass, 16 tests
|
||||
- `cargo test -p manifest builtin_role_profiles_are_registered_and_resolve --lib`: pass, 1 test
|
||||
- `cargo test -p pod builtin_ticket_role_instructions_resolve --lib`: pass, 1 test
|
||||
- `cargo fmt --check`: pass
|
||||
- `git diff --check orchestration/yoi-orchestrator...HEAD`: pass
|
||||
- `./result/bin/yoi ticket doctor`: `doctor: ok`
|
||||
- `nix build .#yoi`: pass
|
||||
|
||||
Next:
|
||||
- Spawn read-only sibling reviewer against the recorded intent, binding decisions/invariants, acceptance criteria, commit `949531a0`, diff, and validation evidence.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: plan author: orchestrator at: 2026-06-12T12:57:29Z -->
|
||||
|
||||
## Plan
|
||||
|
||||
Reviewer delegated.
|
||||
|
||||
- Reviewer Pod: `yoi-reviewer-role-launch-input`
|
||||
- Target branch/worktree: `ticket/shorten-ticket-role-launch-input` at `/home/hare/Projects/yoi/.worktree/shorten-ticket-role-launch-input`
|
||||
- Commit under review: `949531a0 client: shorten ticket role launch input`
|
||||
- Scope: read-only child worktree plus minimal non-recursive runtime-root read required by spawn validation.
|
||||
- Review basis: recorded IntentPacket, binding decisions/invariants, acceptance criteria, implementation summary, diff, and Orchestrator-verified validation evidence.
|
||||
- Reviewer focus: control-plane metadata absence from first-run user text, Instruction/Workflow/Submit boundary, no hidden dynamic context injection, profile instruction resolution, workflow/prompt override safety, and non-brittle tests.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: review author: reviewer:yoi-reviewer-role-launch-input at: 2026-06-12T13:06:54Z status: approve -->
|
||||
|
||||
## Review: approve
|
||||
|
||||
Approve.
|
||||
|
||||
Review target:
|
||||
- Worktree: `/home/hare/Projects/yoi/.worktree/shorten-ticket-role-launch-input`
|
||||
- Commit: `949531a07ede4fd9f82787454ac4d996f25b272d`
|
||||
- Worktree status: clean
|
||||
|
||||
Evidence:
|
||||
- `crates/client/src/ticket_role.rs` の first-run `Segment::Text` は `build_launch_prompt` で対象 Ticket、`Action instruction`、Panel handoff、intent packet、operation/worktree target、validation/report expectations に限定されている。
|
||||
- `profile` / `workflow` / `launch_prompt_ref` / workspace-root 系の制御情報は `TicketRoleLaunchPlan` / `SpawnConfig` 側に残り、Submit text には出ていない。
|
||||
- `WorkflowInvoke` は `Segment::WorkflowInvoke` として別 segment に維持されている。
|
||||
- unit tests は `Configured launch_prompt`、`Profile selector`、`Workflow:`、Ticket record language、`role_workspace_root` / `role_cwd` 等が first-run text に入らないことと、必要な path/branch/validation/report expectation が残ることを直接検証している。
|
||||
- builtin role Profiles は `worker.instruction = "$yoi/role/<role>"` を設定し、`resources/prompts/role/*` に role behavior が移っている。procedural guidance は `resources/workflows/*` に残っている。
|
||||
- 削除された `resources/prompts/ticket_role/*` への production code 参照は残っていない。prompt loader の `$user` / `$workspace` 解決機構と workflow invocation は維持されている。
|
||||
- `git diff --check orchestration/yoi-orchestrator...HEAD` は問題なし。Orchestrator が提示した focused cargo tests、`cargo fmt --check`、`ticket doctor`、`nix build .#yoi` の validation evidence は受け入れ可能。
|
||||
|
||||
Non-blocking risk:
|
||||
- 旧 `.yoi/prompts/ticket_role/*` override は、この surface の削除により launch Submit text には効かなくなる。今回の Ticket では既存 fragment の削除が許容されているため blocker ではないが、外部ユーザー向けには role behavior は Profile instruction、手順は Workflow override へ移す旨を後で案内すると安全。
|
||||
|
||||
---
|
||||
|
||||
<!-- event: implementation_report author: orchestrator at: 2026-06-12T13:08:07Z -->
|
||||
|
||||
## Implementation report
|
||||
|
||||
Integration completed in the Orchestrator workspace.
|
||||
|
||||
Integrated implementation:
|
||||
- Ticket: `00001KTVPS6K3`
|
||||
- Implementation branch: `ticket/shorten-ticket-role-launch-input`
|
||||
- Implementation commit: `949531a0 client: shorten ticket role launch input`
|
||||
- Reviewer result: approve, no blockers
|
||||
- Orchestrator merge commit: `bdbd955b merge: ticket role launch input split`
|
||||
- Integration target: `orchestration/yoi-orchestrator`
|
||||
|
||||
Post-integration validation from Orchestrator worktree:
|
||||
- `cargo test -p client ticket_role --lib`: pass, 16 tests
|
||||
- `cargo test -p manifest builtin_role_profiles_are_registered_and_resolve --lib`: pass, 1 test
|
||||
- `cargo test -p pod builtin_ticket_role_instructions_resolve --lib`: pass, 1 test
|
||||
- `cargo fmt --check`: pass
|
||||
- `git diff --check HEAD~1..HEAD`: pass
|
||||
- `nix build .#yoi`: pass
|
||||
- `./result/bin/yoi ticket doctor`: `doctor: ok`
|
||||
|
||||
Remaining non-blocking risk:
|
||||
- 旧 `.yoi/prompts/ticket_role/*` override は launch Submit text には効かなくなる。今回の Ticket では fragment 削除が許容されているため blocker ではないが、外部ユーザー向けには role behavior は Profile instruction、手順は Workflow override へ移す旨を後続で案内すると安全。
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: orchestrator at: 2026-06-12T13:08:11Z from: inprogress to: done reason: implementation_merged_and_validated field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Implementation was merged into the Orchestrator branch, reviewer approved, and post-integration validation passed. Cleanup and closure will be recorded next.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: implementation_report author: orchestrator at: 2026-06-12T13:08:36Z -->
|
||||
|
||||
## Implementation report
|
||||
|
||||
Cleanup completed.
|
||||
|
||||
- Stopped coder Pod: `yoi-coder-role-launch-input`
|
||||
- Stopped reviewer Pod: `yoi-reviewer-role-launch-input`
|
||||
- Removed child worktree: `/home/hare/Projects/yoi/.worktree/shorten-ticket-role-launch-input`
|
||||
- Deleted implementation branch: `ticket/shorten-ticket-role-launch-input`
|
||||
- Orchestrator worktree status after cleanup: clean
|
||||
|
||||
Cleanup was limited to child implementation worktree/branch and related child Pods. Root/original workspace was not touched.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: hare at: 2026-06-12T13:08:52Z from: done to: closed reason: closed field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Ticket を closed にしました。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: close author: hare at: 2026-06-12T13:08:52Z status: closed -->
|
||||
|
||||
## 完了
|
||||
|
||||
Ticket role launch の first-run user message を短縮し、role behavior / procedural guidance / control-plane metadata の所管を分離した。
|
||||
|
||||
実装概要:
|
||||
- `crates/client/src/ticket_role.rs` の launch Submit text を短縮し、対象 Ticket / action instruction / per-launch context に限定した。
|
||||
- `Profile selector`、`Workflow`、`Configured launch_prompt ref`、Ticket record language guidance、runtime workspace/cwd などの control-plane / environment 情報を first-run user text から外した。
|
||||
- builtin role Profiles に `worker.instruction = "$yoi/role/<role>"` を設定し、role behavior を `resources/prompts/role/{intake,orchestrator,coder,reviewer}.md` へ移した。
|
||||
- procedural guidance は Workflow resources 側に保持・移動した。
|
||||
- obsolete な `resources/prompts/ticket_role/*.md` fragments を削除した。
|
||||
- boundary を検証する focused unit tests を追加・更新した。
|
||||
|
||||
Review / integration:
|
||||
- Implementation commit: `949531a0 client: shorten ticket role launch input`
|
||||
- Reviewer: `yoi-reviewer-role-launch-input` が approve。
|
||||
- Orchestrator merge commit: `bdbd955b merge: ticket role launch input split`
|
||||
- Ticket completion commit: `9ad5ed6d ticket: mark role launch done`
|
||||
|
||||
Validation:
|
||||
- `cargo test -p client ticket_role --lib`: pass
|
||||
- `cargo test -p manifest builtin_role_profiles_are_registered_and_resolve --lib`: pass
|
||||
- `cargo test -p pod builtin_ticket_role_instructions_resolve --lib`: pass
|
||||
- `cargo fmt --check`: pass
|
||||
- `git diff --check HEAD~1..HEAD`: pass
|
||||
- `nix build .#yoi`: pass
|
||||
- `./result/bin/yoi ticket doctor`: `doctor: ok`
|
||||
|
||||
Cleanup:
|
||||
- coder/reviewer Pods stopped。
|
||||
- child worktree `/home/hare/Projects/yoi/.worktree/shorten-ticket-role-launch-input` removed。
|
||||
- branch `ticket/shorten-ticket-role-launch-input` deleted。
|
||||
|
||||
Non-blocking follow-up:
|
||||
- 旧 `.yoi/prompts/ticket_role/*` override は launch Submit text には効かなくなるため、外部ユーザー向けには role behavior は Profile instruction、手順は Workflow override へ移す旨を必要に応じて案内すると安全。
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
//! host-side Pod spawning behind the `client` crate so UI callers do not need to
|
||||
//! depend on `pod` internals.
|
||||
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Duration;
|
||||
|
|
@ -39,13 +38,12 @@ impl TicketRef {
|
|||
non_empty(self.id.as_deref())
|
||||
}
|
||||
|
||||
fn append_prompt_lines(&self, out: &mut String, prompts: &TicketRolePromptTemplates) {
|
||||
fn append_submit_lines(&self, out: &mut String) {
|
||||
match non_empty(self.id.as_deref()) {
|
||||
None => out.push_str("Target Ticket: not specified\n"),
|
||||
Some(id) => {
|
||||
out.push_str("Target Ticket:\n");
|
||||
push_bounded_bullet(out, "id", id);
|
||||
push_prompt_fragment(out, &prompts.ticket_id_guidance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -66,11 +64,10 @@ impl TicketIntakeHandoff {
|
|||
}
|
||||
}
|
||||
|
||||
fn append_prompt_lines(&self, out: &mut String, prompts: &TicketRolePromptTemplates) {
|
||||
fn append_submit_lines(&self, out: &mut String) {
|
||||
out.push_str("\nPanel handoff:\n");
|
||||
push_bounded_bullet(out, "workspace", &self.workspace_label);
|
||||
push_bounded_bullet(out, "workspace_orchestrator_pod", &self.orchestrator_pod);
|
||||
push_prompt_fragment(out, &prompts.intake_handoff);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -286,7 +283,7 @@ pub fn plan_ticket_role_launch_with_config(
|
|||
None => default_pod_name(context.role, context.ticket.as_ref()),
|
||||
};
|
||||
validate_ticket_role_profile(context.role, &profile, &context.workspace_root, &pod_name)?;
|
||||
let prompt = build_launch_prompt(&context, &profile, &workflow, launch_prompt_ref.as_deref());
|
||||
let prompt = build_launch_prompt(&context);
|
||||
|
||||
let original_workspace_root = context.original_workspace_root().to_path_buf();
|
||||
let target_workspace_root = context.target_workspace_root().to_path_buf();
|
||||
|
|
@ -499,154 +496,31 @@ async fn wait_for_run_acceptance(
|
|||
.map_err(|_| TicketRoleLaunchError::RunAcceptanceTimeout)?
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct TicketRolePromptTemplates {
|
||||
launch_preamble: String,
|
||||
ticket_id_guidance: String,
|
||||
record_language_configured: String,
|
||||
record_language_unconfigured: String,
|
||||
intake_handoff: String,
|
||||
orchestrator_worktree_routing: String,
|
||||
orchestrator_merge_completion: String,
|
||||
coder_worktree_routing: String,
|
||||
reviewer_worktree_routing: String,
|
||||
}
|
||||
|
||||
impl TicketRolePromptTemplates {
|
||||
fn load(workspace_root: &Path) -> Self {
|
||||
Self {
|
||||
launch_preamble: load_ticket_role_prompt(
|
||||
workspace_root,
|
||||
"launch_preamble",
|
||||
include_str!("../../../resources/prompts/ticket_role/launch_preamble.md"),
|
||||
),
|
||||
ticket_id_guidance: load_ticket_role_prompt(
|
||||
workspace_root,
|
||||
"ticket_id_guidance",
|
||||
include_str!("../../../resources/prompts/ticket_role/ticket_id_guidance.md"),
|
||||
),
|
||||
record_language_configured: load_ticket_role_prompt(
|
||||
workspace_root,
|
||||
"record_language_configured",
|
||||
include_str!(
|
||||
"../../../resources/prompts/ticket_role/record_language_configured.md"
|
||||
),
|
||||
),
|
||||
record_language_unconfigured: load_ticket_role_prompt(
|
||||
workspace_root,
|
||||
"record_language_unconfigured",
|
||||
include_str!(
|
||||
"../../../resources/prompts/ticket_role/record_language_unconfigured.md"
|
||||
),
|
||||
),
|
||||
intake_handoff: load_ticket_role_prompt(
|
||||
workspace_root,
|
||||
"intake_handoff",
|
||||
include_str!("../../../resources/prompts/ticket_role/intake_handoff.md"),
|
||||
),
|
||||
orchestrator_worktree_routing: load_ticket_role_prompt(
|
||||
workspace_root,
|
||||
"orchestrator_worktree_routing",
|
||||
include_str!(
|
||||
"../../../resources/prompts/ticket_role/orchestrator_worktree_routing.md"
|
||||
),
|
||||
),
|
||||
orchestrator_merge_completion: load_ticket_role_prompt(
|
||||
workspace_root,
|
||||
"orchestrator_merge_completion",
|
||||
include_str!(
|
||||
"../../../resources/prompts/ticket_role/orchestrator_merge_completion.md"
|
||||
),
|
||||
),
|
||||
coder_worktree_routing: load_ticket_role_prompt(
|
||||
workspace_root,
|
||||
"coder_worktree_routing",
|
||||
include_str!("../../../resources/prompts/ticket_role/coder_worktree_routing.md"),
|
||||
),
|
||||
reviewer_worktree_routing: load_ticket_role_prompt(
|
||||
workspace_root,
|
||||
"reviewer_worktree_routing",
|
||||
include_str!("../../../resources/prompts/ticket_role/reviewer_worktree_routing.md"),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_ticket_role_prompt(workspace_root: &Path, name: &str, builtin: &str) -> String {
|
||||
let relative = Path::new("ticket_role").join(format!("{name}.md"));
|
||||
for candidate in [
|
||||
Some(workspace_root.join(".yoi/prompts").join(&relative)),
|
||||
manifest::paths::user_prompts_dir().map(|dir| dir.join(&relative)),
|
||||
]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
{
|
||||
if let Ok(text) = fs::read_to_string(candidate) {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
builtin.to_string()
|
||||
}
|
||||
|
||||
fn push_prompt_fragment(out: &mut String, fragment: &str) {
|
||||
out.push_str(fragment.trim_end());
|
||||
out.push('\n');
|
||||
}
|
||||
|
||||
fn build_launch_prompt(
|
||||
context: &TicketRoleLaunchContext,
|
||||
profile: &str,
|
||||
workflow: &str,
|
||||
launch_prompt_ref: Option<&str>,
|
||||
) -> String {
|
||||
let prompts = TicketRolePromptTemplates::load(&context.workspace_root);
|
||||
fn build_launch_prompt(context: &TicketRoleLaunchContext) -> String {
|
||||
let mut out = String::new();
|
||||
push_prompt_fragment(&mut out, &prompts.launch_preamble);
|
||||
out.push('\n');
|
||||
push_bounded_field(&mut out, "Role", context.role.as_str());
|
||||
push_bounded_field(&mut out, "Profile selector", profile);
|
||||
push_bounded_field(&mut out, "Workflow", workflow);
|
||||
match launch_prompt_ref {
|
||||
Some(prompt_ref) => push_bounded_field(
|
||||
&mut out,
|
||||
"Configured launch_prompt ref (unresolved)",
|
||||
prompt_ref,
|
||||
),
|
||||
None => out.push_str("Configured launch_prompt ref: none\n"),
|
||||
}
|
||||
out.push('\n');
|
||||
match non_empty(context.ticket_record_language.as_deref()) {
|
||||
Some(language) => {
|
||||
push_bounded_field(&mut out, "Ticket record language", language);
|
||||
push_prompt_fragment(&mut out, &prompts.record_language_configured);
|
||||
}
|
||||
None => push_prompt_fragment(&mut out, &prompts.record_language_unconfigured),
|
||||
}
|
||||
out.push('\n');
|
||||
|
||||
if let Some(ticket) = &context.ticket {
|
||||
ticket.append_prompt_lines(&mut out, &prompts);
|
||||
ticket.append_submit_lines(&mut out);
|
||||
} else {
|
||||
out.push_str("Target Ticket: not specified\n");
|
||||
}
|
||||
|
||||
append_workspace_routing_context(&mut out, context);
|
||||
|
||||
match non_empty(context.user_instruction.as_deref()) {
|
||||
Some(instruction) => push_bounded_section(&mut out, "User/action instruction", instruction),
|
||||
None => out.push_str("\nUser/action instruction: not specified\n"),
|
||||
if let Some(instruction) = non_empty(context.user_instruction.as_deref()) {
|
||||
push_bounded_section(&mut out, "Action instruction", instruction);
|
||||
}
|
||||
|
||||
if let Some(handoff) = &context.intake_handoff {
|
||||
handoff.append_prompt_lines(&mut out, &prompts);
|
||||
handoff.append_submit_lines(&mut out);
|
||||
}
|
||||
|
||||
if let Some(intent_packet) = non_empty(context.intent_packet.as_deref()) {
|
||||
push_bounded_section(&mut out, "Intent packet", intent_packet);
|
||||
}
|
||||
|
||||
append_operation_targets(&mut out, context);
|
||||
|
||||
if context.worktree_path.is_some() || non_empty(context.branch.as_deref()).is_some() {
|
||||
out.push_str("\nWorktree context:\n");
|
||||
out.push_str("\nWorktree target:\n");
|
||||
if let Some(path) = &context.worktree_path {
|
||||
push_bounded_bullet(&mut out, "path", &path.display().to_string());
|
||||
}
|
||||
|
|
@ -666,72 +540,29 @@ fn build_launch_prompt(
|
|||
);
|
||||
}
|
||||
|
||||
append_role_execution_guidance(&mut out, context.role, &prompts);
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
fn append_workspace_routing_context(out: &mut String, context: &TicketRoleLaunchContext) {
|
||||
let original_workspace_root = context.original_workspace_root();
|
||||
let implementation_worktree_root = context.implementation_worktree_root();
|
||||
let should_emit = context.original_workspace_root.is_some()
|
||||
|| context.target_workspace_root.is_some()
|
||||
|| context.role == TicketRole::Orchestrator;
|
||||
if !should_emit {
|
||||
fn append_operation_targets(out: &mut String, context: &TicketRoleLaunchContext) {
|
||||
if context.role != TicketRole::Orchestrator {
|
||||
return;
|
||||
}
|
||||
if context.original_workspace_root.is_none() && context.target_workspace_root.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
out.push_str("\nWorkspace routing context:\n");
|
||||
push_bounded_bullet(
|
||||
out,
|
||||
"role_workspace_root",
|
||||
&context.workspace_root.display().to_string(),
|
||||
);
|
||||
if let Some(cwd) = &context.cwd {
|
||||
push_bounded_bullet(out, "role_cwd", &cwd.display().to_string());
|
||||
}
|
||||
push_bounded_bullet(
|
||||
out,
|
||||
"original_workspace_root",
|
||||
&original_workspace_root.display().to_string(),
|
||||
);
|
||||
out.push_str("\nOrchestrator operation targets:\n");
|
||||
push_bounded_bullet(
|
||||
out,
|
||||
"implementation_worktree_root",
|
||||
&implementation_worktree_root.display().to_string(),
|
||||
&context.implementation_worktree_root().display().to_string(),
|
||||
);
|
||||
if context.role == TicketRole::Orchestrator {
|
||||
out.push_str(
|
||||
"- Treat `role_workspace_root` / `role_cwd` as the Orchestrator workspace on the orchestration branch. Use `implementation_worktree_root` only as the placement root for child implementation worktrees; do not operate on `original_workspace_root` itself. Root/original workspace reads, writes, validation, cleanup, and git operations are prohibited. Create implementation branches from the Orchestrator workspace current HEAD / orchestration branch HEAD and integrate reviewed work back into that orchestration branch automatically.\n",
|
||||
if context.target_workspace_root.is_some() {
|
||||
push_bounded_bullet(
|
||||
out,
|
||||
"merge_target_workspace_root",
|
||||
&context.target_workspace_root().display().to_string(),
|
||||
);
|
||||
} else {
|
||||
out.push_str(
|
||||
"- Treat `role_workspace_root` as the launched role runtime workspace/Ticket backend root. Create implementation worktrees under `implementation_worktree_root`, not relative to the role cwd, and run role work against the recorded workspace routing context.\n",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn append_role_execution_guidance(
|
||||
out: &mut String,
|
||||
role: TicketRole,
|
||||
prompts: &TicketRolePromptTemplates,
|
||||
) {
|
||||
match role {
|
||||
TicketRole::Orchestrator => {
|
||||
out.push('\n');
|
||||
push_prompt_fragment(out, &prompts.orchestrator_worktree_routing);
|
||||
out.push('\n');
|
||||
push_prompt_fragment(out, &prompts.orchestrator_merge_completion);
|
||||
}
|
||||
TicketRole::Coder => {
|
||||
out.push('\n');
|
||||
push_prompt_fragment(out, &prompts.coder_worktree_routing);
|
||||
}
|
||||
TicketRole::Reviewer => {
|
||||
out.push('\n');
|
||||
push_prompt_fragment(out, &prompts.reviewer_worktree_routing);
|
||||
}
|
||||
TicketRole::Intake => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -776,13 +607,6 @@ fn sanitise_pod_name_component(value: &str) -> String {
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn push_bounded_field(out: &mut String, label: &str, value: &str) {
|
||||
out.push_str(label);
|
||||
out.push_str(": ");
|
||||
out.push_str(&bounded(value));
|
||||
out.push('\n');
|
||||
}
|
||||
|
||||
fn push_bounded_bullet(out: &mut String, label: &str, value: &str) {
|
||||
out.push_str("- ");
|
||||
out.push_str(label);
|
||||
|
|
@ -1096,7 +920,7 @@ profile = "project:no-such-ticket-role-profile"
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn configured_ticket_record_language_is_included_in_role_prompt() {
|
||||
fn ticket_record_language_stays_out_of_first_run_text() {
|
||||
let temp = TempDir::new().unwrap();
|
||||
write_config(
|
||||
temp.path(),
|
||||
|
|
@ -1113,11 +937,9 @@ profile = "builtin:default"
|
|||
let plan = plan_ticket_role_launch(context).unwrap();
|
||||
let text = text_segment(&plan);
|
||||
|
||||
assert!(text.contains("Ticket record language: Japanese"));
|
||||
assert!(text.contains("write durable Ticket item/thread/resolution text"));
|
||||
assert!(text.contains("does not change normal worker response language"));
|
||||
assert!(text.contains("memory/Knowledge generation language"));
|
||||
assert!(text.contains("Do not translate protocol literals"));
|
||||
assert!(!text.contains("Ticket record language"));
|
||||
assert!(!text.contains("Japanese"));
|
||||
assert!(!text.contains("write durable Ticket item/thread/resolution text"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -1168,7 +990,7 @@ profile = "builtin:default"
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn configured_role_refs_are_exposed_in_plan_and_prompt() {
|
||||
fn configured_role_refs_are_plan_metadata_not_submit_text() {
|
||||
let temp = TempDir::new().unwrap();
|
||||
write_config(
|
||||
temp.path(),
|
||||
|
|
@ -1198,12 +1020,16 @@ workflow = "ticket-review-workflow"
|
|||
&plan.run_segments[0],
|
||||
Segment::WorkflowInvoke { slug } if slug == "ticket-review-workflow"
|
||||
));
|
||||
assert!(text.contains(
|
||||
"Configured launch_prompt ref (unresolved): $workspace/ticket/reviewer/launch"
|
||||
));
|
||||
assert!(text.contains("Workflow: ticket-review-workflow"));
|
||||
assert!(text.contains("Profile selector: builtin:default"));
|
||||
assert!(!text.contains("Configured launch_prompt"));
|
||||
assert!(!text.contains("$workspace/ticket/reviewer/launch"));
|
||||
assert!(!text.contains("Workflow: ticket-review-workflow"));
|
||||
assert!(!text.contains("Profile selector: builtin:default"));
|
||||
assert!(!text.contains("Role: reviewer"));
|
||||
assert!(!text.contains("system_instruction"));
|
||||
assert!(text.contains("Target Ticket:"));
|
||||
assert!(text.contains("id: 20260605-190330-ticket-role-pod-launcher"));
|
||||
assert!(text.contains("Action instruction:"));
|
||||
assert!(text.contains("Review the submitted implementation."));
|
||||
let spawn = plan
|
||||
.spawn_config(PodRuntimeCommand::for_executable("/bin/yoi"))
|
||||
.unwrap();
|
||||
|
|
@ -1214,7 +1040,7 @@ workflow = "ticket-review-workflow"
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn generated_prompt_covers_intake_orchestrator_coder_and_reviewer_context() {
|
||||
fn submit_text_contains_only_ticket_action_and_per_launch_context() {
|
||||
let temp = TempDir::new().unwrap();
|
||||
write_builtin_role_config(
|
||||
temp.path(),
|
||||
|
|
@ -1230,9 +1056,11 @@ workflow = "ticket-review-workflow"
|
|||
intake.user_instruction = Some("Clarify and materialize this request as a Ticket.".into());
|
||||
let intake_plan = plan_ticket_role_launch(intake).unwrap();
|
||||
let intake_text = text_segment(&intake_plan);
|
||||
assert!(intake_text.contains("Role: intake"));
|
||||
assert!(intake_text.contains("Action instruction:"));
|
||||
assert!(intake_text.contains("Clarify and materialize"));
|
||||
assert!(intake_text.contains("Workflow: ticket-intake-workflow"));
|
||||
assert!(!intake_text.contains("Workflow:"));
|
||||
assert!(!intake_text.contains("Profile selector:"));
|
||||
assert!(!intake_text.contains("Role:"));
|
||||
|
||||
let mut handoff_intake = TicketRoleLaunchContext::new(temp.path(), TicketRole::Intake);
|
||||
handoff_intake.intake_handoff = Some(TicketIntakeHandoff::new(
|
||||
|
|
@ -1244,13 +1072,9 @@ workflow = "ticket-review-workflow"
|
|||
assert!(handoff_text.contains("Panel handoff:"));
|
||||
assert!(handoff_text.contains("workspace_orchestrator_pod: panel-orchestrator-demo"));
|
||||
assert!(handoff_text.contains("workspace: Demo workspace"));
|
||||
assert!(handoff_text.contains("created_or_updated_ticket_id"));
|
||||
assert!(handoff_text.contains("state"));
|
||||
assert!(handoff_text.contains("Ticket tool surface"));
|
||||
assert!(handoff_text.contains("ready -> queued"));
|
||||
assert!(handoff_text.contains("queued` as schedulable"));
|
||||
assert!(!handoff_text.contains("user_go_required"));
|
||||
assert!(!handoff_text.contains("human Go gates"));
|
||||
assert!(!handoff_text.contains("created_or_updated_ticket_id"));
|
||||
assert!(!handoff_text.contains("Ticket tool surface"));
|
||||
assert!(!handoff_text.contains("ready -> queued"));
|
||||
|
||||
let mut orchestrator = TicketRoleLaunchContext::new(temp.path(), TicketRole::Orchestrator);
|
||||
orchestrator.ticket = Some(TicketRef::id("launcher"));
|
||||
|
|
@ -1258,27 +1082,15 @@ workflow = "ticket-review-workflow"
|
|||
orchestrator.validation = vec!["cargo check --workspace --all-targets".into()];
|
||||
let orchestrator_plan = plan_ticket_role_launch(orchestrator).unwrap();
|
||||
let orchestrator_text = text_segment(&orchestrator_plan);
|
||||
assert!(orchestrator_text.contains("Role: orchestrator"));
|
||||
assert!(orchestrator_text.contains("id: launcher"));
|
||||
assert!(orchestrator_text.contains("Route to implementation after planning sync."));
|
||||
assert!(orchestrator_text.contains("cargo check --workspace --all-targets"));
|
||||
assert!(orchestrator_text.contains("state = inprogress"));
|
||||
assert!(orchestrator_text.contains("worktree-workflow"));
|
||||
assert!(orchestrator_text.contains("keep tracked `.yoi` project records visible"));
|
||||
assert!(orchestrator_text.contains("exclude `.yoi/memory`"));
|
||||
assert!(
|
||||
orchestrator_text
|
||||
.contains("prohibit creating generated memory/local/runtime/secret-like files")
|
||||
);
|
||||
assert!(orchestrator_text.contains("multi-agent-workflow"));
|
||||
assert!(orchestrator_text.contains("coder and reviewer are siblings"));
|
||||
assert!(orchestrator_text.contains("branch-local reviewer verdicts"));
|
||||
assert!(orchestrator_text.contains("binding decisions/invariants"));
|
||||
assert!(orchestrator_text.contains("not unrecorded preferred tactics"));
|
||||
assert!(orchestrator_text.contains("integration outcome"));
|
||||
assert!(orchestrator_text.contains(
|
||||
"integrate the implementation branch into the orchestration branch automatically"
|
||||
));
|
||||
assert!(orchestrator_text.contains("Root/original workspace reads, writes, validation, cleanup, and git operations are prohibited"));
|
||||
assert!(!orchestrator_text.contains("state = inprogress"));
|
||||
assert!(!orchestrator_text.contains("worktree-workflow"));
|
||||
assert!(!orchestrator_text.contains("multi-agent-workflow"));
|
||||
assert!(!orchestrator_text.contains("root/original workspace reads"));
|
||||
assert!(!orchestrator_text.contains("role_workspace_root"));
|
||||
assert!(!orchestrator_text.contains("role_cwd"));
|
||||
|
||||
let mut coder = TicketRoleLaunchContext::new(temp.path(), TicketRole::Coder);
|
||||
coder.ticket = Some(TicketRef::id("20260605-190330-ticket-role-pod-launcher"));
|
||||
|
|
@ -1288,17 +1100,13 @@ workflow = "ticket-review-workflow"
|
|||
coder.report_expectations = vec!["implementation report with validation".into()];
|
||||
let coder_plan = plan_ticket_role_launch(coder).unwrap();
|
||||
let coder_text = text_segment(&coder_plan);
|
||||
assert!(coder_text.contains("Role: coder"));
|
||||
assert!(coder_text.contains("path: /tmp/yoi-code"));
|
||||
assert!(coder_text.contains("branch: work/ticket-role-pod-launcher"));
|
||||
assert!(coder_text.contains("cargo test -p client ticket_role"));
|
||||
assert!(coder_text.contains("provided child worktree/branch"));
|
||||
assert!(coder_text.contains("do not edit main-workspace `.yoi`"));
|
||||
assert!(coder_text.contains("child-worktree `.yoi` project records may be visible"));
|
||||
assert!(coder_text.contains("Do not create `.yoi/memory`"));
|
||||
assert!(coder_text.contains("implementation latitude"));
|
||||
assert!(coder_text.contains("choose local tactics"));
|
||||
assert!(coder_text.contains("Do not merge, push, close Tickets, or delete worktrees"));
|
||||
assert!(coder_text.contains("implementation report with validation"));
|
||||
assert!(!coder_text.contains("provided child worktree/branch"));
|
||||
assert!(!coder_text.contains("choose local tactics"));
|
||||
assert!(!coder_text.contains("Do not merge, push"));
|
||||
|
||||
let mut reviewer = TicketRoleLaunchContext::new(temp.path(), TicketRole::Reviewer);
|
||||
reviewer.ticket = Some(TicketRef::id("20260605-190330-ticket-role-pod-launcher"));
|
||||
|
|
@ -1307,22 +1115,16 @@ workflow = "ticket-review-workflow"
|
|||
reviewer.report_expectations = vec!["approve or request changes".into()];
|
||||
let reviewer_plan = plan_ticket_role_launch(reviewer).unwrap();
|
||||
let reviewer_text = text_segment(&reviewer_plan);
|
||||
assert!(reviewer_text.contains("Role: reviewer"));
|
||||
assert!(reviewer_text.contains("path: /tmp/yoi-review"));
|
||||
assert!(reviewer_text.contains("branch: work/ticket-role-pod-launcher"));
|
||||
assert!(reviewer_text.contains("approve or request changes"));
|
||||
assert!(reviewer_text.contains("read-only by default"));
|
||||
assert!(reviewer_text.contains("recorded intent, binding decisions/invariants"));
|
||||
assert!(reviewer_text.contains("not unrecorded preferred tactics"));
|
||||
assert!(reviewer_text.contains("Orchestrator-side integration"));
|
||||
assert!(
|
||||
reviewer_text
|
||||
.contains("Do not merge, close, push, operate on the root/original workspace")
|
||||
);
|
||||
assert!(!reviewer_text.contains("read-only by default"));
|
||||
assert!(!reviewer_text.contains("Orchestrator-side integration"));
|
||||
assert!(!reviewer_text.contains("Do not merge, close"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn orchestrator_prompt_covers_orchestration_branch_integration_boundary() {
|
||||
fn orchestrator_submit_exposes_operation_targets_without_runtime_workspace_context() {
|
||||
let temp = TempDir::new().unwrap();
|
||||
write_builtin_role_config(temp.path(), &[TicketRole::Orchestrator]);
|
||||
let mut orchestrator = TicketRoleLaunchContext::new(temp.path(), TicketRole::Orchestrator);
|
||||
|
|
@ -1348,50 +1150,17 @@ workflow = "ticket-review-workflow"
|
|||
assert_eq!(spawn_config.workspace_root, temp.path());
|
||||
assert_eq!(spawn_config.cwd, None);
|
||||
|
||||
assert!(text.contains("Workspace routing context:"));
|
||||
assert!(text.contains("role_workspace_root"));
|
||||
assert!(text.contains("Orchestrator operation targets:"));
|
||||
assert!(text.contains("implementation_worktree_root"));
|
||||
assert!(text.contains("Orchestrator workspace on the orchestration branch"));
|
||||
assert!(text.contains("Root/original workspace reads, writes, validation, cleanup, and git operations are prohibited"));
|
||||
assert!(text.contains("Create implementation branches from the Orchestrator workspace current HEAD / orchestration branch HEAD"));
|
||||
assert!(
|
||||
text.contains(
|
||||
"integrate reviewed work back into that orchestration branch automatically"
|
||||
)
|
||||
);
|
||||
assert!(text.contains("Orchestrator implementation integration guidance"));
|
||||
assert!(
|
||||
text.contains("Integrate only within the Orchestrator workspace/orchestration branch")
|
||||
);
|
||||
assert!(text.contains("root/original workspace is not an integration target"));
|
||||
assert!(text.contains("merge or otherwise integrate that implementation branch into the orchestration branch automatically"));
|
||||
assert!(text.contains(
|
||||
"Run post-integration validation from the Orchestrator workspace/orchestration branch"
|
||||
));
|
||||
assert!(text.contains("Cleanup is limited to the child implementation worktree/branch"));
|
||||
assert!(text.contains("merge_target_workspace_root"));
|
||||
assert!(!text.contains("Workspace routing context:"));
|
||||
assert!(!text.contains("role_workspace_root"));
|
||||
assert!(!text.contains("role_cwd"));
|
||||
assert!(!text.contains("original_workspace_root"));
|
||||
assert!(!text.contains("Orchestrator workspace on the orchestration branch"));
|
||||
assert!(!text.contains("Root/original workspace reads, writes, validation, cleanup, and git operations are prohibited"));
|
||||
assert!(!text.contains("Orchestrator implementation integration guidance"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workspace_prompt_override_replaces_ticket_role_fragment() {
|
||||
let temp = TempDir::new().unwrap();
|
||||
write_builtin_role_config(temp.path(), &[TicketRole::Orchestrator]);
|
||||
let override_dir = temp.path().join(".yoi/prompts/ticket_role");
|
||||
std::fs::create_dir_all(&override_dir).unwrap();
|
||||
std::fs::write(
|
||||
override_dir.join("orchestrator_worktree_routing.md"),
|
||||
"Orchestrator worktree + agent routing guidance:\n- WORKSPACE OVERRIDE MARKER\n",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut orchestrator = TicketRoleLaunchContext::new(temp.path(), TicketRole::Orchestrator);
|
||||
orchestrator.ticket = Some(TicketRef::id("prompt-resource-override"));
|
||||
let plan = plan_ticket_role_launch(orchestrator).unwrap();
|
||||
let text = text_segment(&plan);
|
||||
|
||||
assert!(text.contains("WORKSPACE OVERRIDE MARKER"));
|
||||
assert!(!text.contains("Use `multi-agent-workflow`"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn caller_provided_pod_name_is_used_exactly() {
|
||||
let temp = TempDir::new().unwrap();
|
||||
|
|
|
|||
|
|
@ -1588,6 +1588,10 @@ mod tests {
|
|||
Some(expected)
|
||||
);
|
||||
assert_eq!(resolved.manifest.pod.name, "role-pod");
|
||||
if matches!(expected, "intake" | "orchestrator" | "coder" | "reviewer") {
|
||||
let expected_instruction = format!("$yoi/role/{expected}");
|
||||
assert_eq!(resolved.manifest.worker.instruction, expected_instruction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -316,6 +316,16 @@ mod tests {
|
|||
assert!(!source.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_ticket_role_instructions_resolve() {
|
||||
let loader = PromptLoader::builtins_only();
|
||||
for role in ["intake", "orchestrator", "coder", "reviewer"] {
|
||||
let (reference, source) = loader.resolve(&format!("$yoi/role/{role}"), None).unwrap();
|
||||
assert_eq!(reference.to_qualified_string(), format!("$yoi/role/{role}"));
|
||||
assert!(source.contains("first committed user message"));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_subdirectory_lookup() {
|
||||
let loader = PromptLoader::builtins_only();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ return yoi.profile.extend("builtin:default", {
|
|||
|
||||
scope = yoi.scope.workspace_write(),
|
||||
|
||||
worker = {
|
||||
instruction = "$yoi/role/coder",
|
||||
},
|
||||
|
||||
feature = {
|
||||
task = { enabled = true },
|
||||
memory = { enabled = true },
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ return yoi.profile.extend("builtin:default", {
|
|||
|
||||
scope = yoi.scope.workspace_read(),
|
||||
|
||||
worker = {
|
||||
instruction = "$yoi/role/intake",
|
||||
},
|
||||
|
||||
feature = {
|
||||
task = { enabled = false },
|
||||
memory = { enabled = true },
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ return yoi.profile.extend("builtin:default", {
|
|||
|
||||
scope = yoi.scope.workspace_read(),
|
||||
|
||||
worker = {
|
||||
instruction = "$yoi/role/orchestrator",
|
||||
},
|
||||
|
||||
feature = {
|
||||
task = { enabled = false },
|
||||
memory = { enabled = true },
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ return yoi.profile.extend("builtin:default", {
|
|||
|
||||
scope = yoi.scope.workspace_read(),
|
||||
|
||||
worker = {
|
||||
instruction = "$yoi/role/reviewer",
|
||||
},
|
||||
|
||||
feature = {
|
||||
task = { enabled = false },
|
||||
memory = { enabled = true },
|
||||
|
|
|
|||
7
resources/prompts/role/coder.md
Normal file
7
resources/prompts/role/coder.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
You are the Ticket Coder role.
|
||||
|
||||
Keep role behavior here and treat the first committed user message as concrete Ticket/action context only. Implement only within the delegated worktree/branch and authority scope. Treat the Ticket, intent packet, binding decisions/invariants, implementation latitude, validation expectations, and report expectations as the contract.
|
||||
|
||||
Choose local implementation tactics within that contract. Escalate to the Orchestrator instead of expanding scope when design, permission, dependency, prompt-boundary, or Ticket-boundary questions appear. Do not merge, push, close Tickets, delete worktrees, or create generated memory/local/runtime/log/lock/cache/socket/secret-like `.yoi` state.
|
||||
|
||||
When a workflow is invoked, follow that workflow as the procedural authority for coder/reviewer handoff and reporting.
|
||||
5
resources/prompts/role/intake.md
Normal file
5
resources/prompts/role/intake.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
You are the Ticket Intake role.
|
||||
|
||||
Keep role behavior here and treat the first committed user message as concrete Ticket/action context only. Clarify ambiguous user requests, create or update the appropriate Ticket through typed Ticket tools, and leave implementation side effects to the user/Orchestrator queue flow. Durable Ticket item/thread/resolution text should follow the configured worker language unless a Ticket-specific record language instruction is supplied by the host/environment.
|
||||
|
||||
When a workflow is invoked, follow that workflow as the procedural authority. Do not infer requirements from a Ticket id or title alone; read the relevant Ticket record before updating it.
|
||||
7
resources/prompts/role/orchestrator.md
Normal file
7
resources/prompts/role/orchestrator.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
You are the Ticket Orchestrator role.
|
||||
|
||||
Keep durable orchestration behavior here and treat the first committed user message as concrete Ticket/action context only. Use typed Ticket tools and current repository state as authority. Record `inprogress` before implementation side effects, route concrete work to sibling Coder/Reviewer Pods when appropriate, and stop for human authority when merge/closure is not explicitly delegated.
|
||||
|
||||
Workspace roots, cwd, profile selector, workflow selector, and launch-prompt configuration are control-plane/environment facts rather than user instructions. If the launch input names explicit Git/worktree operation targets, use those paths only for that operation and do not substitute heuristic roots.
|
||||
|
||||
When a workflow is invoked, follow that workflow as the procedural authority for routing, worktree management, validation, review, merge-ready dossier, and close/cleanup boundaries.
|
||||
5
resources/prompts/role/reviewer.md
Normal file
5
resources/prompts/role/reviewer.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
You are the Ticket Reviewer role.
|
||||
|
||||
Keep role behavior here and treat the first committed user message as concrete Ticket/action context only. Review the implementation against the Ticket intent, binding decisions/invariants, acceptance criteria, and project design boundaries. Prefer read-only inspection and focused validation; do not merge, close, clean up worktrees, or take over implementation unless explicitly asked.
|
||||
|
||||
Report clear approve/request-changes evidence with risks, validation performed, and any unresolved requirement or design-boundary concern. When a workflow is invoked, follow that workflow as the procedural authority for reviewer handoff and report shape.
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
Coder worktree routing guidance:
|
||||
- Implement only in the provided child worktree/branch. SpawnPod should set `cwd` to that worktree so Bash/tool defaults already start there; do not treat `cwd` as authority, and do not edit main-workspace `.yoi`, Ticket, workflow, docs, or memory records; child-worktree `.yoi` project records may be visible when they are part of the branch.
|
||||
- Do not create `.yoi/memory`, local/runtime state, logs, locks, caches, sockets, or secret-like files in the child worktree.
|
||||
- Treat the intent packet, binding decisions/invariants, implementation latitude, validation expectations, and report expectations as the contract. Investigate and choose local tactics only within the recorded implementation latitude; escalate to Orchestrator rather than expanding scope when design, permission, history, prompt-context, dependency, or Ticket-boundary questions appear.
|
||||
- Report worktree path, branch, commits/status, changed files, implementation summary, validation run, unresolved notes, and whether the branch is ready for external review. Do not merge, push, close Tickets, or delete worktrees.
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
- When Intake has clarified the request and created/updated the Ticket, use the typed Ticket tool surface to append `intake_summary` and set `state = ready` when the Ticket is ready to queue; use planning language for Tickets that still need clarification/preparation.
|
||||
- Handoff report fields: created_or_updated_ticket_id, state, open_questions_or_risk_flags, intake_summary.
|
||||
- Do not start implementation automatically; the user queues a ready Ticket via panel (`ready -> queued`), and Orchestrator treats `queued` as schedulable before moving it to `inprogress` when starting.
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# Ticket role launch
|
||||
|
||||
Profile supplies durable system/role behavior. The workflow segment supplies the procedural flow. This generated launch prompt supplies only the concrete Ticket/action context for the first committed user task.
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
Orchestrator implementation integration guidance:
|
||||
- Integrate only within the Orchestrator workspace/orchestration branch. The root/original workspace is not an integration target and must not be read, written, validated, cleaned, or touched with git.
|
||||
- Treat the child implementation branch as work targeting the orchestration branch. After coder completion, reviewer approval, and blocker resolution, merge or otherwise integrate that implementation branch into the orchestration branch automatically.
|
||||
- Before integration, verify the dossier identities: Ticket id/title/state, child worktree path, child branch name, commits/diff, reviewer verdict, validation evidence, and any unresolved blockers.
|
||||
- Run post-integration validation from the Orchestrator workspace/orchestration branch. Do not run validation from the root/original workspace and do not rely on root workspace state for the decision.
|
||||
- Record the integration result, validation evidence, and any remaining risks in the Ticket thread visible in the Orchestrator worktree. If the Ticket requirements are satisfied, advance the Ticket lifecycle in that worktree.
|
||||
- Cleanup is limited to the child implementation worktree/branch and related child Pods. Do not remove, reset, merge, fast-forward, close, or otherwise mutate the root/original workspace.
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
Orchestrator worktree + agent routing guidance:
|
||||
- Treat `ticket-orchestrator-routing` as the routing gate. Read the Ticket and Orchestrator workspace state first; `ready -> queued` authorizes routing, not implementation side effects.
|
||||
- Work only in the Orchestrator workspace/orchestration branch and child implementation worktrees. Do not operate on the original/root workspace: no reads for decision evidence, no writes, no validation, no Ticket edits, no cleanup, and no git operations there.
|
||||
- If the launch context includes `original_workspace_root` or `implementation_worktree_root`, use those paths only to choose child implementation worktree placement under `.worktree`. The root workspace itself is not a work target.
|
||||
- Create implementation branches from the Orchestrator workspace current HEAD / orchestration branch HEAD, not from root/develop. After reviewer approval and blocker resolution, integrate the implementation branch into the orchestration branch automatically; do not wait for root-side promotion.
|
||||
- Create worktrees or spawn coder/reviewer Pods only after `state = inprogress` is already recorded and accepted. If the Ticket is still queued and unblocked, record `queued -> inprogress` before any worktree/SpawnPod side effect.
|
||||
- Use `worktree-workflow` for the mechanical worktree plan: create the child implementation worktree under the recorded implementation worktree root, keep tracked `.yoi` project records visible in the child worktree, and exclude `.yoi/memory` plus local/runtime/log/lock/secret-like `.yoi` paths.
|
||||
- Use `multi-agent-workflow` for the sibling loop: coder and reviewer are siblings under this Orchestrator; coder gets narrow write scope to the child worktree; reviewer is read-only by default.
|
||||
- Give the coder an intent packet that distinguishes binding decisions/invariants, implementation latitude, escalation conditions, child worktree/branch, validation commands, and report expectations; set SpawnPod `cwd` to the child worktree while delegating explicit scope separately, prohibit editing root workspace records, and prohibit creating generated memory/local/runtime/secret-like files in the child worktree.
|
||||
- Give the reviewer the recorded Ticket intent, binding decisions/invariants, implementation latitude, acceptance criteria, explicit escalation conditions, diff/commits, validation evidence, and blocker/non-blocker criteria; reviewer judgment is against recorded requirements and decisions, not unrecorded preferred tactics. Keep branch-local reviewer verdicts in the review report or orchestration dossier.
|
||||
- Ticket thread progress may record worktree plan, coder delegated/completed/blocked, reviewer delegated, blocker/fix-loop summaries, integration outcome, validation evidence, and cleanup outcome in the Orchestrator workspace.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Ticket record language guidance: write durable Ticket item/thread/resolution text and Ticket tool bodies in this language. This does not change normal worker response language or memory/Knowledge generation language. Do not translate protocol literals, file paths, commands, logs, identifiers, or quoted external text solely because this language is configured.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Ticket record language: not configured; preserve existing/default Ticket record language behavior.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
Reviewer worktree routing guidance:
|
||||
- Review as a sibling of the coder under Orchestrator, read-only by default. Read the Ticket/intent packet, branch diff or commits, and validation evidence before judging. Judge implementation against recorded intent, binding decisions/invariants, implementation latitude, acceptance criteria, and explicit escalation conditions, not unrecorded preferred tactics.
|
||||
- Classify findings as blockers, non-blocking follow-ups, or parent-decision items against the recorded intent, binding decisions/invariants, implementation latitude, acceptance criteria, and explicit escalation conditions; include concrete file/line evidence where useful.
|
||||
- Keep the branch-local reviewer verdict in the review report for Orchestrator-side integration. Do not merge, close, push, operate on the root/original workspace, or instruct the coder directly.
|
||||
|
|
@ -1 +0,0 @@
|
|||
- Treat the Ticket id as an opaque storage id. Read TicketShow body/thread/artifacts before routing or implementation; do not infer requirements from id or title alone.
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
---
|
||||
description: Public sibling coder/reviewer workflow
|
||||
model_invokation: false
|
||||
description: worktree と sibling の coder / reviewer Pod を使い、下位 orchestrator が concrete Ticket 群の実装・外部レビュー・修正・完了準備を管理する orchestration フロー
|
||||
model_invokation: true
|
||||
user_invocable: true
|
||||
requires: [workflow-resource-boundary]
|
||||
---
|
||||
# Multi-agent Workflow
|
||||
|
||||
Use sibling implementation and review roles for a bounded Ticket. The Orchestrator owns intent, acceptance boundaries, blocker decisions, final merge-completion authority, and cleanup. The coder implements within delegated scope; the reviewer checks the recorded Ticket intent and acceptance criteria rather than unrecorded preferences.
|
||||
# Multi-agent workflow
|
||||
|
||||
Produce a merge-ready dossier with Ticket id, branch/worktree, commits, implementation summary, reviewer verdict, validation evidence, residual risks, dirty state, and any remaining human decision needs.
|
||||
1. Orchestrator は concrete Ticket intent、binding decisions/invariants、implementation latitude、validation expectations、report expectations、worktree path、branch を Coder に渡す。Coder は delegated child worktree/branch のみを編集し、main/root workspace、merge、push、Ticket close、worktree cleanup、generated `.yoi` runtime/local/memory/log/lock/cache/socket/secret-like state を触らない。
|
||||
2. Coder は local tactics を選んで実装し、変更ファイル・summary・validation・commit/status・unresolved notes・review readiness を報告する。design/permission/history/prompt-context/dependency/Ticket-boundary の未決事項は Orchestrator に escalate する。
|
||||
3. Reviewer は Ticket/intent packet、binding decisions/invariants、acceptance criteria、diff/commits、validation evidence を読んでから判断する。実装を recorded requirements と project design boundary に照らして review し、blocker / non-blocking follow-up / parent-decision item を分類する。
|
||||
4. Reviewer report は approve/request-changes evidence、file/line evidence where useful、validation performed、risks、unresolved concerns を含める。Reviewer は merge、close、push、cleanup、root/original workspace operation、Coder への直接指示を行わない。
|
||||
5. Orchestrator は blocker fix loop、review approval、merge-ready dossier、integration/cleanup/close authority を管理する。下位 Pod の completion notification は transient hint とし、durable output/session/worktree state で確認する。
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
---
|
||||
description: Public Ticket intake requirements-sync workflow
|
||||
description: ユーザーの曖昧な依頼を要件同期し、合意済みの Ticket として作成・更新する Intake workflow
|
||||
model_invokation: true
|
||||
user_invocable: true
|
||||
requires: [workflow-resource-boundary]
|
||||
---
|
||||
# Ticket Intake Workflow
|
||||
|
||||
Clarify a user request until it can be represented as a concrete Ticket. Preserve user intent, write bounded requirements and acceptance criteria, and avoid creating duplicate or umbrella Tickets when a more concrete Ticket is appropriate.
|
||||
# Ticket intake workflow
|
||||
|
||||
Do not perform implementation side effects. If an existing Ticket is refined, make scope/readiness changes explicit and keep broad changes as drafts until user agreement is clear.
|
||||
1. ユーザー依頼と既存 Ticket を同期し、重複作成を避ける。既存 Ticket を対象にする場合は body/thread/artifacts を読んでから更新する。
|
||||
2. 要件・背景・受け入れ条件・未決事項を Ticket に記録する。実装手順は必要になるまで増やしすぎない。
|
||||
3. Ticket が queue 可能な粒度と明確さになったら、typed Ticket tool surface で intake summary を残し、`state = ready` にする。未決事項がある場合は planning に留め、必要な質問やリスクを明示する。
|
||||
4. Handoff report は `created_or_updated_ticket_id`、`state`、`open_questions_or_risk_flags`、`intake_summary` を含める。
|
||||
5. Intake は実装を開始しない。ユーザーが panel 等で `ready -> queued` し、Orchestrator が queued Ticket を routing する。
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
---
|
||||
description: Public Ticket orchestrator routing workflow
|
||||
description: Ticket を読み、Orchestrator が planning return / spike / implementation / review / blocked / close へ明示的に routing する workflow
|
||||
model_invokation: true
|
||||
user_invocable: true
|
||||
requires: [workflow-resource-boundary]
|
||||
---
|
||||
# Ticket Orchestrator Routing Workflow
|
||||
|
||||
Read the Ticket, relation metadata, orchestration-plan records, and relevant workspace state before deciding the next action. Treat `queued -> inprogress` as the implementation acceptance marker and record it before worktree creation, role Pod spawn, or other implementation side effects.
|
||||
# Ticket orchestrator routing workflow
|
||||
|
||||
Classify the Ticket as planning return, blocked, spike, implementation-ready, review-needed, close-ready, or noop. If implementation-ready, record an IntentPacket with binding decisions, implementation latitude, acceptance criteria, escalation conditions, validation, and reviewer focus.
|
||||
1. Ticket body/thread/artifacts/resolution 状態を読み、current state と blocking relation を確認する。queued Ticket は実装 side effect 前に `inprogress` を記録する。
|
||||
2. 不足情報が具体的にある場合は planning return とし、何が足りないかを Ticket thread に残す。risk flag は context lookup・review focus・invariant・escalation として扱い、自動 stop gate にしない。
|
||||
3. 実装に進む場合は Orchestrator workspace/orchestration HEAD を基準にし、launch input の explicit Git/worktree operation target だけを使う。role workspace/cwd は環境情報であり、original/root workspace を読み書き・検証・cleanup・git 操作対象にしない。
|
||||
4. child implementation worktree は recorded implementation worktree root 配下に作成し、implementation branch は Orchestrator workspace current HEAD / orchestration branch HEAD から切る。Coder/Reviewer は sibling Pods として route し、Ticket intent・binding decisions・validation/report expectations を concrete handoff として渡す。
|
||||
5. Reviewer が request-changes した場合は、scope 内で Coder に修正を戻すか、Orchestrator が blocked/escalation を記録する。approve evidence が揃うまで merge-ready とみなさない。
|
||||
6. merge completion authority が無い場合は、Ticket/branch/commit identity、intent/invariant check、implementation summary、coder/reviewer evidence、blocker resolution、validation、risks、dirty state、decision needs を含む merge-ready dossier で停止する。
|
||||
7. 明示 authority と clean reviewer evidence がある場合のみ、merge target workspace への統合、validation、Ticket close/completion processing、関連 Pod 停止、scope reclamation、worktree/branch cleanup、evidence reporting を進める。
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user