chore: update orchestration and plugin tickets
This commit is contained in:
parent
adebedc021
commit
d66dfbbbc2
|
|
@ -2,7 +2,7 @@
|
|||
title: 'Plugin distribution package format and discovery'
|
||||
state: 'planning'
|
||||
created_at: '2026-06-01T06:49:53Z'
|
||||
updated_at: '2026-06-13T15:29:21Z'
|
||||
updated_at: '2026-06-14T14:34:33Z'
|
||||
---
|
||||
|
||||
## Background
|
||||
|
|
@ -13,8 +13,8 @@ MCP is intentionally not modeled as a Plugin package/runtime in this Ticket. MCP
|
|||
|
||||
The desired initial direction is a single-file plugin package that can be placed in user or workspace plugin stores, for example:
|
||||
|
||||
- `~/.config/yoi/plugins/<id>.yoi-plugin`
|
||||
- `./.yoi/plugins/<id>.yoi-plugin`
|
||||
- `${XDG_DATA_HOME:-~/.local/share}/yoi/plugins/<id>.yoi-plugin`
|
||||
- `<workspace>/.yoi/plugins/<id>.yoi-plugin`
|
||||
|
||||
The package should be easy to copy, inspect, cache, and pin while preserving Yoi's scope, permission, history, prompt-context, and trust invariants. Workspace plugins may come from a repository checkout and must not execute merely because an archive exists under `./.yoi/plugins`.
|
||||
|
||||
|
|
@ -26,10 +26,11 @@ The package should be easy to copy, inspect, cache, and pin while preserving Yoi
|
|||
- Support packaged assets such as `module.wasm`, JSON schemas, README, and license files.
|
||||
- Specify archive safety rules, including path traversal rejection, bounded extraction, and deterministic digest calculation.
|
||||
- Define plugin stores and source/trust mapping.
|
||||
- User plugin store: `~/.config/yoi/plugins/`.
|
||||
- Workspace/project plugin store: `./.yoi/plugins/`.
|
||||
- Map stores to the existing source vocabulary (`User`, `Project`/workspace, and future `Builtin`).
|
||||
- Treat `user:<id>` and `project:<id>` as distinct plugin references; ambiguous unqualified IDs should fail closed.
|
||||
- User plugin store: `${XDG_DATA_HOME:-~/.local/share}/yoi/plugins/`.
|
||||
- Workspace/project plugin store: `<workspace>/.yoi/plugins/`.
|
||||
- Builtin plugin source: Yoi-distributed `builtin:` registry.
|
||||
- Map stores to the source vocabulary (`user`, `project`, `builtin`).
|
||||
- Treat `user:<id>` and `project:<id>` as distinct plugin references; ambiguous unqualified IDs fail closed.
|
||||
- Separate discovery from enablement.
|
||||
- Yoi may discover plugin packages in configured stores.
|
||||
- Discovered packages must not register Tools/Hooks, initialize WASM, start services, or start MCP servers until explicitly enabled by manifest/profile configuration.
|
||||
|
|
@ -80,7 +81,7 @@ The package should be easy to copy, inspect, cache, and pin while preserving Yoi
|
|||
## Acceptance criteria
|
||||
|
||||
- The repository has a documented plugin distribution/package proposal covering user and workspace plugin stores, single-file archive format, manifest fields, archive safety, cache/digest behavior, and discovery vs enablement.
|
||||
- The proposal explicitly states that placing a package in `~/.config/yoi/plugins/` or `./.yoi/plugins/` is discovery only, not execution or registration.
|
||||
- The proposal explicitly states that placing a package in `${XDG_DATA_HOME:-~/.local/share}/yoi/plugins/` or `<workspace>/.yoi/plugins/` is discovery only, not execution or registration.
|
||||
- The design maps package sources to user/project/builtin trust categories and defines how ID collisions and ambiguous selectors are handled.
|
||||
- The design explains Plugin permission requests/grants as Plugin-layer policy, distinct from `pod::feature` authority/grant concepts.
|
||||
- Runtime-specific notes cover declarative hooks and WASM packages; MCP is called out as a separate feature-backed integration, not part of initial Plugin packaging.
|
||||
|
|
|
|||
|
|
@ -37,4 +37,17 @@ Distribution direction from user discussion:
|
|||
- `00001KSXRQ4G8` と `00001KT0Z4BK8` は Plugin permission を Plugin layer として扱い、MCP を初期 Plugin packaging/runtime から分離する。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: decision author: hare at: 2026-06-14T14:34:33Z -->
|
||||
|
||||
## Decision
|
||||
|
||||
決定:
|
||||
- Plugin discovery stores, source-qualified identity, discovery/enablement separation, Pod-startup initialization timing, restore behavior, and MCP boundaryをこの `00001KT0Z4BK8` の安定 contract として統合した。
|
||||
- User Plugin package store は `${XDG_DATA_HOME:-~/.local/share}/yoi/plugins/` とし、`~/.config/yoi/plugins/` は使わない。
|
||||
- Package presence は discovery only であり、実行・登録・runtime initialization は explicit enablement 後の Pod startup に限定する。
|
||||
- Restore は metadata snapshot の enabled Plugin plan を正本とし、fresh discovery で silent upgrade しない。
|
||||
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: "Preserve active workflows across compaction"
|
||||
state: "planning"
|
||||
state: 'ready'
|
||||
created_at: "2026-06-07T02:23:28Z"
|
||||
updated_at: "2026-06-07T02:23:28Z"
|
||||
updated_at: '2026-06-14T14:13:43Z'
|
||||
---
|
||||
|
||||
## Background
|
||||
|
|
|
|||
|
|
@ -5,3 +5,61 @@
|
|||
Created by LocalTicketBackend create.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: comment author: ticket-intake at: 2026-06-14T14:13:35Z -->
|
||||
|
||||
## Comment
|
||||
|
||||
## Intake refinement
|
||||
|
||||
既存 Ticket `00001KTFY8V80` を確認した。新規 duplicate Ticket は作成しない。
|
||||
|
||||
### Readiness
|
||||
|
||||
- readiness: implementation_ready
|
||||
- risk_flags: [prompt-context, persistence, workflow-state, compaction]
|
||||
|
||||
この Ticket は、active workflow を compaction / rehydration 後も継続可能にする concrete work item として十分に bounded されている。実装戦術の調査余地は残るが、Orchestrator が implementation routing できる要件・受け入れ条件・検証観点は揃っている。
|
||||
|
||||
### Binding decisions / invariants
|
||||
|
||||
- active workflow の進行中状態を、history に残らない transient context 注入だけで復元してはならない。
|
||||
- compaction / restore 後に「どの workflow が継続中か」「どの手順段階・義務が残っているか」をモデルが説明可能でなければならない。
|
||||
- workflow state の復元は、prompt context 加工原則に反しない形で durable source から再構成する。
|
||||
- missing / corrupt / obsolete workflow state は fail-closed または bounded diagnostic として扱い、silently stale instructions を実行しない。
|
||||
- Ticket / Pod history / workflow record / compaction output の authority boundary を混同しない。
|
||||
|
||||
### Implementation latitude
|
||||
|
||||
- workflow state の永続化先・schema・snapshot 粒度は、既存 Pod/session/compaction architecture に合わせて選んでよい。
|
||||
- active workflow body を invocation-time snapshot として保持するか、rehydration 時に最新 resource を参照するかは、実装時に明示的に決定し、互換性・安全性の理由をコードまたは docs / Ticket 報告に残す。
|
||||
- UI/diagnostic 表示の具体的な文言や internal field 名は、既存設計に沿って調整してよい。
|
||||
|
||||
### Escalation conditions
|
||||
|
||||
- workflow snapshot vs latest body の選択が authority boundary または backward compatibility を大きく変える場合。
|
||||
- compaction が workflow obligations を再現するために hidden context injection を必要としそうな場合。
|
||||
- persisted workflow state の migration / compatibility 方針が既存 records を破壊する場合。
|
||||
- implementation が Ticket lifecycle / Orchestrator queue semantics / workflow invocation semantics を広げる必要を見つけた場合。
|
||||
|
||||
### Related context checked
|
||||
|
||||
- closed `00001KTG3AZQ8` / `00001KTG3BX0R` は Orchestrator routing / merge completion の完了済み関連文脈であり、本 Ticket の duplicate ではない。
|
||||
|
||||
---
|
||||
|
||||
<!-- event: intake_summary author: ticket-intake at: 2026-06-14T14:13:43Z -->
|
||||
|
||||
## Intake summary
|
||||
|
||||
既存 Ticket `00001KTFY8V80` を精査し、duplicate は作成しない方針で refinement を記録した。対象は active Workflow invocation/state/obligations を durable state/history と compaction/rehydration 経路に載せ、compaction 後も `/multi-agent-workflow` / `/worktree-workflow` などの active obligations を traceable に継続できるようにする実装 work item。readiness は implementation_ready。risk flags は prompt-context / persistence / workflow-state / compaction。Orchestrator は implementation routing 可能だが、snapshot vs latest workflow body の選択、hidden context injection 回避、missing/corrupt persisted state の fail-closed diagnostic、Ticket/Pod/history/workflow authority boundary を reviewer focus に含める。
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: ticket-intake at: 2026-06-14T14:13:43Z from: planning to: ready reason: intake_ready field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Intake refinement が完了し、要件・受け入れ条件・binding invariants・escalation conditions が Ticket thread に記録されたため `planning -> ready` にします。実装 side effects は Orchestrator routing 後に行います。
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: 'Extend pod::feature API for external protocol-backed capability providers'
|
||||
state: 'done'
|
||||
state: 'closed'
|
||||
created_at: '2026-06-10T07:48:14Z'
|
||||
updated_at: '2026-06-14T06:39:48Z'
|
||||
updated_at: '2026-06-14T14:00:13Z'
|
||||
assignee: null
|
||||
readiness: 'implementation_ready'
|
||||
risk_flags: ['feature-api', 'tool-registry', 'permission-scope', 'prompt-context', 'dynamic-registry', 'service-lifecycle']
|
||||
|
|
|
|||
1
.yoi/tickets/00001KTR81P9X/resolution.md
Normal file
1
.yoi/tickets/00001KTR81P9X/resolution.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Closed after prior done-state completion.
|
||||
|
|
@ -178,4 +178,22 @@ Next:
|
|||
|
||||
Implementation branch was reviewed, approved, merged into the Orchestrator branch as `3d140dbb`, and validated in the Orchestrator worktree. Feature-provider focused tests, formatting, diff check, and workspace check passed. Ticket implementation work is done; closure remains separate.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: hare at: 2026-06-14T14:00:13Z from: done to: closed reason: closed field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Ticket を closed にしました。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: close author: hare at: 2026-06-14T14:00:13Z status: closed -->
|
||||
|
||||
## 完了
|
||||
|
||||
Closed after prior done-state completion.
|
||||
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: 'Profile extend API を廃止して import + Lua 代入に寄せる'
|
||||
state: 'done'
|
||||
state: 'closed'
|
||||
created_at: '2026-06-13T07:31:09Z'
|
||||
updated_at: '2026-06-14T06:34:34Z'
|
||||
updated_at: '2026-06-14T14:00:13Z'
|
||||
assignee: null
|
||||
readiness: 'implementation_ready'
|
||||
risk_flags: ['profiles', 'lua-api', 'builtin-resources', 'migration']
|
||||
|
|
|
|||
1
.yoi/tickets/00001KTZY8HK2/resolution.md
Normal file
1
.yoi/tickets/00001KTZY8HK2/resolution.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Closed after prior done-state completion.
|
||||
|
|
@ -179,4 +179,22 @@ Next:
|
|||
|
||||
Implementation branch was reviewed, approved, merged into the Orchestrator branch as `58b15ee6`, and validated in the Orchestrator worktree. Focused manifest profile tests, formatting, diff check, `cargo build -p yoi`, and `nix build .#yoi` passed after cleanup freed disk space. Ticket implementation work is done; closure remains separate.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: hare at: 2026-06-14T14:00:13Z from: done to: closed reason: closed field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Ticket を closed にしました。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: close author: hare at: 2026-06-14T14:00:13Z status: closed -->
|
||||
|
||||
## 完了
|
||||
|
||||
Closed after prior done-state completion.
|
||||
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: 'Workspace panel: show Ticket-associated Intake Pods adjacent to Ticket rows'
|
||||
state: 'planning'
|
||||
state: 'ready'
|
||||
created_at: '2026-06-13T10:54:31Z'
|
||||
updated_at: '2026-06-13T10:54:31Z'
|
||||
updated_at: '2026-06-14T14:12:11Z'
|
||||
assignee: null
|
||||
readiness: 'implementation_ready'
|
||||
risk_flags: ['panel-ux', 'local-role-session-registry', 'pod-session-state']
|
||||
|
|
|
|||
|
|
@ -5,3 +5,19 @@
|
|||
LocalTicketBackend によって作成されました。
|
||||
|
||||
---
|
||||
|
||||
<!-- event: intake_summary author: ticket-intake at: 2026-06-14T14:12:11Z -->
|
||||
|
||||
## Intake summary
|
||||
|
||||
既存 Ticket 00001KV09WYC6 の body/thread/artifacts を確認した。要件、受け入れ条件、binding decisions / invariants、implementation latitude、escalation conditions、validation が揃っており、readiness は `implementation_ready` と判断できる。未解決の blocking open question はない。risk_flags は `panel-ux`, `local-role-session-registry`, `pod-session-state`。次は Orchestrator が routing し、実装時は Panel の selection/keyboard semantics、one-active-claim-per-Ticket invariant、pre-Ticket Intake の誤関連付け回避、registry schema migration 不要の維持を重点確認する。
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: ticket-intake at: 2026-06-14T14:12:11Z from: planning to: ready reason: planning_ready field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Intake 確認により、既存 Ticket の要件は実装 routing 可能な状態と判断した。実装 side effect は Orchestrator の queue/routing flow に委ねる。
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: 'Panel から ready Ticket を指示付きで planning に戻して Intake を再開できるようにする'
|
||||
state: 'done'
|
||||
state: 'closed'
|
||||
created_at: '2026-06-13T10:54:34Z'
|
||||
updated_at: '2026-06-14T05:09:07Z'
|
||||
updated_at: '2026-06-14T14:00:13Z'
|
||||
assignee: null
|
||||
readiness: 'implementation_ready'
|
||||
risk_flags: ['panel-action', 'ticket-lifecycle', 'role-session', 'authority-boundary']
|
||||
|
|
|
|||
1
.yoi/tickets/00001KV09X0XC/resolution.md
Normal file
1
.yoi/tickets/00001KV09X0XC/resolution.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Closed after prior done-state completion.
|
||||
|
|
@ -182,4 +182,22 @@ Next:
|
|||
|
||||
Implementation branch was reviewed, approved, merged into the Orchestrator branch as `7a6321d9`, and validated in the Orchestrator worktree. Focused TUI planning-return/intake/workspace-panel tests, Ticket tests, formatting, and diff check passed. Ticket implementation work is done; closure remains separate.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: hare at: 2026-06-14T14:00:13Z from: done to: closed reason: closed field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Ticket を closed にしました。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: close author: hare at: 2026-06-14T14:00:13Z status: closed -->
|
||||
|
||||
## 完了
|
||||
|
||||
Closed after prior done-state completion.
|
||||
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: 'Remove feature-layer HostAuthority model'
|
||||
state: 'done'
|
||||
state: 'closed'
|
||||
created_at: '2026-06-13T15:30:22Z'
|
||||
updated_at: '2026-06-13T19:02:01Z'
|
||||
updated_at: '2026-06-14T14:00:13Z'
|
||||
assignee: null
|
||||
readiness: 'implementation_ready'
|
||||
risk_flags: ['feature-api', 'tool-registry', 'ticket-tools']
|
||||
|
|
|
|||
1
.yoi/tickets/00001KV0SP0TY/resolution.md
Normal file
1
.yoi/tickets/00001KV0SP0TY/resolution.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Closed after prior done-state completion.
|
||||
|
|
@ -205,4 +205,22 @@ Next:
|
|||
|
||||
Implementation branch was reviewed, approved, merged into the Orchestrator branch as `297e95ef`, and validated in the Orchestrator worktree. Focused pod/ticket tests, formatting, diff check, and `cargo check --workspace --all-targets` passed after cleanup freed disk space. Ticket implementation work is done; closure remains separate.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: hare at: 2026-06-14T14:00:13Z from: done to: closed reason: closed field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Ticket を closed にしました。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: close author: hare at: 2026-06-14T14:00:13Z status: closed -->
|
||||
|
||||
## 完了
|
||||
|
||||
Closed after prior done-state completion.
|
||||
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: 'Panel Orchestrator の orchestration branch 名を ticket.config.toml で設定可能にする'
|
||||
state: 'done'
|
||||
state: 'closed'
|
||||
created_at: '2026-06-13T16:29:25Z'
|
||||
updated_at: '2026-06-14T05:05:57Z'
|
||||
updated_at: '2026-06-14T14:00:13Z'
|
||||
assignee: null
|
||||
readiness: 'implementation_ready'
|
||||
risk_flags: ['config-schema', 'git-worktree', 'panel-orchestration']
|
||||
|
|
|
|||
1
.yoi/tickets/00001KV0X254D/resolution.md
Normal file
1
.yoi/tickets/00001KV0X254D/resolution.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Closed after prior done-state completion.
|
||||
|
|
@ -189,4 +189,22 @@ Next:
|
|||
|
||||
Implementation branch was reviewed, approved, merged into the Orchestrator branch as `290c4230`, and validated in the Orchestrator worktree. Focused ticket config / TUI orchestration worktree / configured branch / queue action tests, formatting, diff check, `cargo build -p yoi`, and `yoi ticket doctor` passed. Ticket implementation work is done; closure remains separate.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: hare at: 2026-06-14T14:00:13Z from: done to: closed reason: closed field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Ticket を closed にしました。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: close author: hare at: 2026-06-14T14:00:13Z status: closed -->
|
||||
|
||||
## 完了
|
||||
|
||||
Closed after prior done-state completion.
|
||||
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: 'E2E harness を完全な tmp runtime/data/workspace 隔離と cleanup に対応させる'
|
||||
state: 'done'
|
||||
state: 'closed'
|
||||
created_at: '2026-06-13T16:56:11Z'
|
||||
updated_at: '2026-06-13T17:33:53Z'
|
||||
updated_at: '2026-06-14T14:00:13Z'
|
||||
assignee: null
|
||||
readiness: 'ready'
|
||||
queued_by: 'yoi ticket'
|
||||
|
|
|
|||
1
.yoi/tickets/00001KV0YK5S0/resolution.md
Normal file
1
.yoi/tickets/00001KV0YK5S0/resolution.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Closed after prior done-state completion.
|
||||
|
|
@ -192,4 +192,22 @@ Next:
|
|||
|
||||
E2E tmp/runtime isolation follow-up was reviewed, merged into the Orchestrator branch as `20184eeb`, and validated in the Orchestrator worktree. Panel E2E now uses clean per-scenario tmp workspace/data/runtime fixtures, preserves artifacts under `target/e2e-artifacts`, removes fixture temp roots after runs, and does not inherit host runtime/credential environment. Ticket implementation work is done; closure remains separate.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: hare at: 2026-06-14T14:00:13Z from: done to: closed reason: closed field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Ticket を closed にしました。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: close author: hare at: 2026-06-14T14:00:13Z status: closed -->
|
||||
|
||||
## 完了
|
||||
|
||||
Closed after prior done-state completion.
|
||||
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: 'E2E: close remaining critical-path gaps after panel harness'
|
||||
state: 'done'
|
||||
state: 'closed'
|
||||
created_at: '2026-06-13T17:34:41Z'
|
||||
updated_at: '2026-06-14T05:39:03Z'
|
||||
updated_at: '2026-06-14T14:00:13Z'
|
||||
assignee: null
|
||||
readiness: 'implementation_ready'
|
||||
risk_flags: ['e2e', 'tui', 'pty', 'quit-latency', 'mouse-input', 'rewind']
|
||||
|
|
|
|||
1
.yoi/tickets/00001KV10SN02/resolution.md
Normal file
1
.yoi/tickets/00001KV10SN02/resolution.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Closed after prior done-state completion.
|
||||
|
|
@ -298,4 +298,22 @@ Next:
|
|||
|
||||
Implementation branch was reviewed, approved, merged into the Orchestrator branch as `059b1fd4`, and validated in the Orchestrator worktree. Focused E2E, TUI rewind/mouse tests, formatting, diff check, `cargo build -p yoi`, and `nix build .#yoi` passed. Ticket implementation work is done; closure remains separate.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: hare at: 2026-06-14T14:00:13Z from: done to: closed reason: closed field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Ticket を closed にしました。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: close author: hare at: 2026-06-14T14:00:13Z status: closed -->
|
||||
|
||||
## 完了
|
||||
|
||||
Closed after prior done-state completion.
|
||||
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: 'Profile から concrete scope を外して launch policy で付与する'
|
||||
state: 'done'
|
||||
state: 'closed'
|
||||
created_at: '2026-06-13T17:45:32Z'
|
||||
updated_at: '2026-06-14T07:04:22Z'
|
||||
updated_at: '2026-06-14T14:00:13Z'
|
||||
assignee: null
|
||||
readiness: 'implementation_ready'
|
||||
risk_flags: ['scope', 'delegation-scope', 'profiles', 'launch-policy', 'orchestrator', 'spawnpod', 'restore']
|
||||
|
|
|
|||
1
.yoi/tickets/00001KV11DHGZ/resolution.md
Normal file
1
.yoi/tickets/00001KV11DHGZ/resolution.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Closed after prior done-state completion.
|
||||
|
|
@ -210,4 +210,22 @@ Next:
|
|||
|
||||
Implementation branch was reviewed, approved, merged into the Orchestrator branch as `3a67b95b`, and validated in the Orchestrator worktree. Focused manifest/client/pod launch-policy/scope/restore tests, build, formatting, diff check, and `nix build .#yoi` passed. Ticket implementation work is done; closure remains separate.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: hare at: 2026-06-14T14:00:13Z from: done to: closed reason: closed field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Ticket を closed にしました。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: close author: hare at: 2026-06-14T14:00:13Z status: closed -->
|
||||
|
||||
## 完了
|
||||
|
||||
Closed after prior done-state completion.
|
||||
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: 'Panel Ticket rows を2行表示にして gate 情報を分離する'
|
||||
state: 'done'
|
||||
state: 'closed'
|
||||
created_at: '2026-06-13T18:10:57Z'
|
||||
updated_at: '2026-06-14T06:42:04Z'
|
||||
updated_at: '2026-06-14T14:00:13Z'
|
||||
assignee: null
|
||||
readiness: 'implementation_ready'
|
||||
risk_flags: ['tui', 'workspace-panel', 'ticket-relations', 'mouse-input', 'layout']
|
||||
|
|
|
|||
1
.yoi/tickets/00001KV12W2RT/resolution.md
Normal file
1
.yoi/tickets/00001KV12W2RT/resolution.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Closed after prior done-state completion.
|
||||
|
|
@ -147,4 +147,22 @@ Next:
|
|||
|
||||
Implementation branch was reviewed, approved, merged into the Orchestrator branch as `a9ece1dc`, and validated in the Orchestrator worktree. Focused TUI row/mouse/gate tests, Panel E2E tests, build, formatting, and diff check passed. Ticket implementation work is done; closure remains separate.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: state_changed author: hare at: 2026-06-14T14:00:13Z from: done to: closed reason: closed field: state -->
|
||||
|
||||
## State changed
|
||||
|
||||
Ticket を closed にしました。
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: close author: hare at: 2026-06-14T14:00:13Z status: closed -->
|
||||
|
||||
## 完了
|
||||
|
||||
Closed after prior done-state completion.
|
||||
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
|
@ -16,6 +16,9 @@ use thiserror::Error;
|
|||
pub const TICKET_CONFIG_RELATIVE_PATH: &str = ".yoi/ticket.config.toml";
|
||||
/// Workspace-relative default root for the built-in local Ticket backend.
|
||||
pub const DEFAULT_TICKET_BACKEND_RELATIVE_PATH: &str = ".yoi/tickets";
|
||||
const DEFAULT_ORCHESTRATION_BRANCH: &str = "orchestration";
|
||||
const DEFAULT_ORCHESTRATION_WORKTREE_DIR: &str = ".worktree";
|
||||
const DEFAULT_ORCHESTRATION_WORKTREE_NAME: &str = "orchestration";
|
||||
|
||||
/// Return the explicit workspace Ticket config scaffold written by `yoi ticket init`.
|
||||
///
|
||||
|
|
@ -36,7 +39,7 @@ pub fn ticket_config_scaffold() -> String {
|
|||
"\n# Optional durable Ticket record language. When unset, generated Ticket text keeps current defaults.\n# [ticket]\n# language = \"Japanese\"\n",
|
||||
);
|
||||
out.push_str(
|
||||
"\n# Optional Panel Orchestrator worktree branch. When unset, Panel uses orchestration/<workspace-orchestrator-pod-name>.\n# [orchestration]\n# branch = \"orchestration/<workspace-orchestrator-pod-name>\"\n",
|
||||
"\n# Optional Panel Orchestrator worktree settings. When unset, Panel uses branch `orchestration` at `.worktree/orchestration`.\n# [orchestration]\n# branch = \"orchestration\"\n# worktree_dir = \".worktree\"\n# worktree_name = \"orchestration\"\n",
|
||||
);
|
||||
for role in TicketRole::ALL {
|
||||
out.push_str(&format!(
|
||||
|
|
@ -77,12 +80,30 @@ pub struct TicketConfig {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||
pub struct TicketOrchestrationConfig {
|
||||
pub branch: Option<GitBranchName>,
|
||||
pub worktree_dir: Option<PathBuf>,
|
||||
pub worktree_name: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl TicketOrchestrationConfig {
|
||||
pub fn branch_name(&self) -> Option<&str> {
|
||||
self.branch.as_ref().map(GitBranchName::as_str)
|
||||
}
|
||||
|
||||
pub fn effective_branch_name(&self) -> &str {
|
||||
self.branch_name().unwrap_or(DEFAULT_ORCHESTRATION_BRANCH)
|
||||
}
|
||||
|
||||
pub fn worktree_dir(&self) -> &Path {
|
||||
self.worktree_dir
|
||||
.as_deref()
|
||||
.unwrap_or_else(|| Path::new(DEFAULT_ORCHESTRATION_WORKTREE_DIR))
|
||||
}
|
||||
|
||||
pub fn worktree_name(&self) -> &Path {
|
||||
self.worktree_name
|
||||
.as_deref()
|
||||
.unwrap_or_else(|| Path::new(DEFAULT_ORCHESTRATION_WORKTREE_NAME))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
|
||||
|
|
@ -167,6 +188,27 @@ fn validate_git_branch_name_value(value: &str) -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_orchestration_relative_path(path: &Path, label: &str) -> Result<(), String> {
|
||||
if path.as_os_str().is_empty() {
|
||||
return Err(format!("{label} must not be empty"));
|
||||
}
|
||||
if path.is_absolute() {
|
||||
return Err(format!("{label} must be workspace-relative"));
|
||||
}
|
||||
for component in path.components() {
|
||||
match component {
|
||||
Component::Normal(_) => {}
|
||||
Component::CurDir | Component::ParentDir => {
|
||||
return Err(format!("{label} must not contain `.` or `..` components"));
|
||||
}
|
||||
Component::RootDir | Component::Prefix(_) => {
|
||||
return Err(format!("{label} must be workspace-relative"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl TicketConfig {
|
||||
pub fn default_for_workspace(workspace_root: impl AsRef<Path>) -> Self {
|
||||
let workspace_root = workspace_root.as_ref();
|
||||
|
|
@ -636,13 +678,25 @@ struct RawTicketConfig {
|
|||
struct RawTicketOrchestrationConfig {
|
||||
#[serde(default)]
|
||||
branch: Option<GitBranchName>,
|
||||
#[serde(default)]
|
||||
worktree_dir: Option<PathBuf>,
|
||||
#[serde(default)]
|
||||
worktree_name: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl RawTicketOrchestrationConfig {
|
||||
fn resolve(self) -> TicketOrchestrationConfig {
|
||||
TicketOrchestrationConfig {
|
||||
branch: self.branch,
|
||||
fn resolve(self) -> Result<TicketOrchestrationConfig, String> {
|
||||
if let Some(path) = &self.worktree_dir {
|
||||
validate_orchestration_relative_path(path, "orchestration.worktree_dir")?;
|
||||
}
|
||||
if let Some(path) = &self.worktree_name {
|
||||
validate_orchestration_relative_path(path, "orchestration.worktree_name")?;
|
||||
}
|
||||
Ok(TicketOrchestrationConfig {
|
||||
branch: self.branch,
|
||||
worktree_dir: self.worktree_dir,
|
||||
worktree_name: self.worktree_name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -691,7 +745,12 @@ impl RawTicketConfig {
|
|||
}
|
||||
})?,
|
||||
ticket: self.ticket.resolve(),
|
||||
orchestration: self.orchestration.resolve(),
|
||||
orchestration: self.orchestration.resolve().map_err(|message| {
|
||||
TicketConfigError::Invalid {
|
||||
path: path.to_path_buf(),
|
||||
message,
|
||||
}
|
||||
})?,
|
||||
roles,
|
||||
})
|
||||
}
|
||||
|
|
@ -797,6 +856,15 @@ mod tests {
|
|||
);
|
||||
assert_eq!(config.ticket_record_language(), None);
|
||||
assert_eq!(config.orchestration.branch_name(), None);
|
||||
assert_eq!(
|
||||
config.orchestration.effective_branch_name(),
|
||||
"orchestration"
|
||||
);
|
||||
assert_eq!(config.orchestration.worktree_dir(), Path::new(".worktree"));
|
||||
assert_eq!(
|
||||
config.orchestration.worktree_name(),
|
||||
Path::new("orchestration")
|
||||
);
|
||||
for role in TicketRole::ALL {
|
||||
let role_config = config.role(role);
|
||||
assert_eq!(role_config.profile.as_str(), "inherit");
|
||||
|
|
@ -820,6 +888,8 @@ language = "Japanese"
|
|||
|
||||
[orchestration]
|
||||
branch = "orchestration/custom-panel"
|
||||
worktree_dir = "custom-worktrees"
|
||||
worktree_name = "custom-orchestrator"
|
||||
|
||||
[roles.intake]
|
||||
profile = "project:intake"
|
||||
|
|
@ -854,6 +924,18 @@ workflow = "multi-agent-workflow"
|
|||
config.orchestration.branch_name(),
|
||||
Some("orchestration/custom-panel")
|
||||
);
|
||||
assert_eq!(
|
||||
config.orchestration.effective_branch_name(),
|
||||
"orchestration/custom-panel"
|
||||
);
|
||||
assert_eq!(
|
||||
config.orchestration.worktree_dir(),
|
||||
Path::new("custom-worktrees")
|
||||
);
|
||||
assert_eq!(
|
||||
config.orchestration.worktree_name(),
|
||||
Path::new("custom-orchestrator")
|
||||
);
|
||||
assert_eq!(
|
||||
config.profile_for(TicketRole::Intake).as_str(),
|
||||
"project:intake"
|
||||
|
|
@ -881,7 +963,7 @@ workflow = "multi-agent-workflow"
|
|||
assert!(scaffold.contains("root = \".yoi/tickets\""));
|
||||
assert!(scaffold.contains("# [ticket]\n# language = \"Japanese\""));
|
||||
assert!(scaffold.contains(
|
||||
"# [orchestration]\n# branch = \"orchestration/<workspace-orchestrator-pod-name>\""
|
||||
"# [orchestration]\n# branch = \"orchestration\"\n# worktree_dir = \".worktree\"\n# worktree_name = \"orchestration\""
|
||||
));
|
||||
for role in TicketRole::ALL {
|
||||
assert!(scaffold.contains(&format!("[roles.{role}]")));
|
||||
|
|
@ -901,6 +983,15 @@ workflow = "multi-agent-workflow"
|
|||
.unwrap();
|
||||
assert_eq!(config.backend_root(), temp.path().join(".yoi/tickets"));
|
||||
assert_eq!(config.orchestration.branch_name(), None);
|
||||
assert_eq!(
|
||||
config.orchestration.effective_branch_name(),
|
||||
"orchestration"
|
||||
);
|
||||
assert_eq!(config.orchestration.worktree_dir(), Path::new(".worktree"));
|
||||
assert_eq!(
|
||||
config.orchestration.worktree_name(),
|
||||
Path::new("orchestration")
|
||||
);
|
||||
for role in TicketRole::ALL {
|
||||
let role_config = config.role_launch_config(role).unwrap();
|
||||
assert_eq!(role_config.profile.as_str(), role.default_profile());
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use ratatui::text::{Line, Span};
|
|||
use ratatui::widgets::{Block, Borders, Clear, Paragraph, Widget, Wrap};
|
||||
use serde::Serialize;
|
||||
use session_store::FsStore;
|
||||
use ticket::config::{GitBranchName, TicketConfig};
|
||||
use ticket::config::{GitBranchName, TicketConfig, TicketOrchestrationConfig};
|
||||
use ticket::{
|
||||
LocalTicketBackend, MarkdownText, TicketBackend, TicketIdOrSlug, TicketStateChange,
|
||||
TicketWorkflowState,
|
||||
|
|
@ -2517,40 +2517,37 @@ struct OrchestrationWorktreeReady {
|
|||
status: OrchestrationWorktreeStatus,
|
||||
}
|
||||
|
||||
fn orchestration_worktree_layout_for_branch(
|
||||
fn orchestration_worktree_layout_for_config(
|
||||
workspace_root: &Path,
|
||||
branch: String,
|
||||
orchestration: &TicketOrchestrationConfig,
|
||||
) -> OrchestrationWorktreeLayout {
|
||||
let stem = workspace_orchestrator_pod_name(workspace_root);
|
||||
OrchestrationWorktreeLayout {
|
||||
path: workspace_root
|
||||
.join(".worktree")
|
||||
.join("orchestration")
|
||||
.join(&stem),
|
||||
branch,
|
||||
.join(orchestration.worktree_dir())
|
||||
.join(orchestration.worktree_name()),
|
||||
branch: orchestration.effective_branch_name().to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn orchestration_worktree_layout(workspace_root: &Path) -> OrchestrationWorktreeLayout {
|
||||
let stem = workspace_orchestrator_pod_name(workspace_root);
|
||||
orchestration_worktree_layout_for_branch(workspace_root, format!("orchestration/{stem}"))
|
||||
OrchestrationWorktreeLayout {
|
||||
path: workspace_root.join(".worktree").join("orchestration"),
|
||||
branch: "orchestration".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn resolved_orchestration_worktree_layout(
|
||||
workspace_root: &Path,
|
||||
) -> Result<OrchestrationWorktreeLayout, String> {
|
||||
let config = TicketConfig::load_workspace(workspace_root)
|
||||
.map_err(|err| format!("failed to load ticket config for orchestration branch: {err}"))?;
|
||||
let branch = if let Some(branch) = config.orchestration.branch_name() {
|
||||
branch.to_string()
|
||||
} else {
|
||||
orchestration_worktree_layout(workspace_root).branch
|
||||
};
|
||||
GitBranchName::new(branch.clone())
|
||||
.map_err(|err| format!("failed to load ticket config for orchestration worktree: {err}"))?;
|
||||
let branch = config.orchestration.effective_branch_name();
|
||||
GitBranchName::new(branch.to_string())
|
||||
.map_err(|message| format!("invalid orchestration branch `{branch}`: {message}"))?;
|
||||
Ok(orchestration_worktree_layout_for_branch(
|
||||
Ok(orchestration_worktree_layout_for_config(
|
||||
workspace_root,
|
||||
branch,
|
||||
&config.orchestration,
|
||||
))
|
||||
}
|
||||
|
||||
|
|
@ -5757,9 +5754,9 @@ mod tests {
|
|||
let layout = orchestration_worktree_layout(root);
|
||||
assert_eq!(
|
||||
layout.path,
|
||||
PathBuf::from("/tmp/Yoi Workspace/.worktree/orchestration/yoi-workspace-orchestrator")
|
||||
PathBuf::from("/tmp/Yoi Workspace/.worktree/orchestration")
|
||||
);
|
||||
assert_eq!(layout.branch, "orchestration/yoi-workspace-orchestrator");
|
||||
assert_eq!(layout.branch, "orchestration");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -5834,7 +5831,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_and_restore_use_configured_orchestration_branch() {
|
||||
fn ensure_and_restore_use_configured_orchestration_layout() {
|
||||
let temp = TempDir::new().unwrap();
|
||||
let root = temp.path().join("repo");
|
||||
init_test_repo(&root);
|
||||
|
|
@ -5843,6 +5840,8 @@ mod tests {
|
|||
r#"
|
||||
[orchestration]
|
||||
branch = "orchestration/custom-panel"
|
||||
worktree_dir = "custom-worktrees"
|
||||
worktree_name = "panel"
|
||||
"#,
|
||||
);
|
||||
run_test_git(&root, &["add", ".yoi/ticket.config.toml"]).unwrap();
|
||||
|
|
@ -5850,11 +5849,7 @@ branch = "orchestration/custom-panel"
|
|||
|
||||
let resolved = resolved_orchestration_worktree_layout(&root).unwrap();
|
||||
assert_eq!(resolved.branch, "orchestration/custom-panel");
|
||||
assert!(
|
||||
resolved
|
||||
.path
|
||||
.ends_with(".worktree/orchestration/repo-orchestrator")
|
||||
);
|
||||
assert!(resolved.path.ends_with("custom-worktrees/panel"));
|
||||
|
||||
let created = ensure_orchestration_worktree(&root).unwrap();
|
||||
assert_eq!(created.status, OrchestrationWorktreeStatus::Created);
|
||||
|
|
@ -5934,12 +5929,7 @@ branch = "orchestration/custom-panel"
|
|||
assert_eq!(restored.status, OrchestrationWorktreeStatus::Reused);
|
||||
assert_eq!(restored.layout.path, created.layout.path);
|
||||
assert_ne!(restored.layout.path, root);
|
||||
assert!(
|
||||
restored
|
||||
.layout
|
||||
.path
|
||||
.ends_with(".worktree/orchestration/repo-orchestrator")
|
||||
);
|
||||
assert!(restored.layout.path.ends_with(".worktree/orchestration"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user