ticket: add workspace identity initialization

This commit is contained in:
Keisuke Hirata 2026-06-23 15:44:29 +09:00
parent 5428837605
commit eb998f0ad4
No known key found for this signature in database
3 changed files with 141 additions and 0 deletions

View File

@ -0,0 +1,117 @@
---
title: 'Persist local Workspace identity in .yoi/workspace.toml'
state: 'ready'
created_at: '2026-06-23T06:43:28Z'
updated_at: '2026-06-23T06:44:19Z'
assignee: null
---
## 背景
Workspace server の local dev bootstrap は現在、`workspace_id` を `local:{display}` のように workspace root の basename から導出している。これは暫定 namespace としては分かりやすいが、DB の primary key / Workspace identity としては不適切である。
問題:
- `workspace_id` が表示名 / path basename から予測可能に作られている。
- 同じ basename の workspace が複数あると衝突しうる。
- workspace root の rename / move で identity が変わる。
- `local:` namespace と display label が DB PK に混ざっている。
- `--workspace .` のような相対 path では display fallback に落ちるなど、初期化責務が `ServerConfig::local_dev` に寄りすぎている。
Workspace identity は `.yoi/workspace.toml` を local Workspace record として永続化し、未作成なら Workspace backend の初期化処理で払い出す。これにより、DB を再作成しても Workspace identity は維持され、将来の DB authority / hosted Workspace / migration でも扱いやすくなる。
## 方針
- `.yoi/workspace.toml` を local Workspace identity の authority とする。
- `workspace_id` は path / display name から導出しない。
- 新規 local Workspace 初期化時に UUIDv7 を発行して `workspace_id` として保存する。
- `display_name` は identity ではなく UI label として保存する。
- 初期値は canonicalized workspace root の basename でよい。
- 将来的に rename 可能な field として扱う。
- `ServerConfig::local_dev` は Workspace ID を生成しない。
- CLI/bootstrap 層で workspace root canonicalization と `.yoi/workspace.toml` load-or-init を行い、結果を `ServerConfig` に渡す。
- `.yoi/workspace.toml` が壊れている場合は勝手に上書きせず、明示的な error で止める。
- 既存 `.yoi/workspace.db` 内の `local:*` workspace row については、初期実装では destructive migration を必須にしない。
- 新しい UUIDv7 workspace row を upsert し、古い row は残してよい。
- 必要なら後続で cleanup/migration policy を設計する。
## `.yoi/workspace.toml` v0
最小 schema:
```toml
workspace_id = "0197..." # UUIDv7 canonical string
created_at = "2026-06-23T...Z"
display_name = "yoi"
```
Validation:
- `workspace_id` は UUID として parse できること。
- 可能なら UUID version 7 であることを検証する。
- `created_at` は RFC3339 UTC timestamp として parse できること。
- `display_name` は空文字列でないこと。
- unknown fields の扱いは将来拡張を考え、明示的に決める。
- v0 では deny でも preserve でもよいが、選択理由を実装に残す。
## 初期化フロー
`yoi-workspace-server serve --workspace <path>` の local bootstrap は将来的に以下の責務分離にする。
1. `--workspace` を canonicalize する。
2. workspace root 配下の `.yoi/` を確認し、なければ作成する。
3. `.yoi/workspace.toml` を読む。
4. 存在しない場合:
- UUIDv7 `workspace_id` を発行する。
- `created_at` を現在 UTC にする。
- `display_name` を canonicalized workspace root basename から作る。
- `.yoi/workspace.toml` を atomic-ish に書き込む。
5. 存在する場合:
- parse / validate する。
- 壊れていたら停止し、上書きしない。
6. `ServerConfig` には canonicalized workspace root と Workspace identity を渡す。
7. SQLite `workspaces` row は `.yoi/workspace.toml``workspace_id` / `display_name` で upsert する。
8. API `/api/workspace` は DB row / identity record を元に stable id と display name を返す。
## 実装候補
- `crates/workspace-server` に Workspace identity loader を追加する。
- 例: `workspace_identity.rs` または `identity.rs`
- 型例:
```rust
struct WorkspaceIdentity {
workspace_id: Uuid,
created_at: DateTime<Utc>,
display_name: String,
}
impl WorkspaceIdentity {
fn load_or_init(root: &Path) -> Result<Self, WorkspaceIdentityError>;
}
```
- `uuid` crate の UUIDv7 support を確認し、必要なら依存 feature を追加する。
- TOML parse/write には既存 dependency を優先し、なければ最小 dependency を検討する。
- `ServerConfig::local_dev``workspace_id` / `display_name` を引数または identity object で受け取る形に寄せる。
## Non-goals
- Hosted / multi-user Workspace identity の完全設計。
- Workspace rename UI。
- 既存 `.yoi/workspace.db` の destructive migration。
- Ticket / Objective storage の DB authority migration。
- `.yoi/workspace.toml` を全 Workspace settings store に拡張すること。
## 受け入れ条件
- local Workspace identity が `.yoi/workspace.toml` に永続化される。
- `.yoi/workspace.toml` 未作成時、Workspace backend 初期化時に UUIDv7 `workspace_id` が払い出される。
- `workspace_id` が path basename / display name から導出されなくなる。
- `display_name``.yoi/workspace.toml` の field として扱われ、identity と分離されている。
- `--workspace .` でも canonicalized workspace root をもとに初期化される。
- `.yoi/workspace.toml` が壊れている場合、勝手に再生成/上書きせず error で停止する。
- `ServerConfig::local_dev` または同等の bootstrap helper が workspace id を自前生成しない。
- SQLite `workspaces` row は `.yoi/workspace.toml` の identity を使って upsert される。
- 既存 `local:{display}` 形式は新規 workspace id として生成されない。
- `cargo test -p yoi-workspace-server`、`git diff --check`、`nix build .#yoi --no-link` が通る。

View File

@ -0,0 +1,24 @@
<!-- event: create author: "yoi ticket" at: 2026-06-23T06:43:28Z -->
## 作成
LocalTicketBackend によって作成されました。
---
<!-- event: intake_summary author: hare at: 2026-06-23T06:44:19Z -->
## Intake summary
Marked ready by `yoi ticket state`.
---
<!-- event: state_changed author: "yoi ticket" at: 2026-06-23T06:44:19Z from: planning to: ready reason: cli_state field: state -->
## State changed
Marked ready by `yoi ticket state`.
---