7.6 KiB
7.6 KiB
作成
LocalTicketBackend によって作成されました。
Plan
背景:
yoi.profile.extend("builtin:default", { scope = yoi.scope.workspace_read() })は、Lua レベルの deep merge により base のscope.intent = "workspace_write"と override の object が merge される。- その後の
PodManifestConfig::mergeでも scope allow/deny は加算されるため、role profile がworkspace_read()を指定してもbuiltin:default由来の direct workspace write が残り得る。 - 今回の暫定対応では Orchestrator profile を
scope = "workspace_read"/delegation_scope = "workspace_write"にして、object merge ではなく scalar replacement を使った。
要件:
- Profile 継承は維持する。
scope/delegation_scopeのような authority-bearing field について、意図的に inherited value を置換またはクリアできる API を設計する。- role profile が default profile の model / compaction / feature defaults 等を継承しつつ、direct authority だけを安全に narrower scope へ置換できるようにする。
- 空 object
{}で消せるようにするか、yoi.profile.replace(...)/yoi.scope.replace(...)/replace = trueなどの明示 API にするかは設計で決める。 - 不注意な権限拡張や hidden fallback を避け、resolved profile の authority が読みやすいこと。
受け入れ条件:
- Orchestrator role profile が
builtin:defaultを継承しても direct workspace write を要求しないことを test で確認する。 - 既存 profile API 互換を壊す場合は、移行対象を明示する。
scopeとdelegation_scopeの merge/replace semantics が docs または test 名から読み取れる。
Decision
決定:
yoi.profile.extendに replace/clear API を足す方向ではなく、extend自体を廃止する。- Profile 継承は
local p = yoi.profile.import("builtin:default"); p.field = ...; return pの ordinary Lua assignment に寄せる。 - deep merge helper が必要なら、semantics が明示された別 API として後続で検討する。
- scope/delegation_scope の問題は
00001KV11DHGZで launch policy に移すため、この Ticket では scope replacement API を作らない。
State changed
Ticket を workspace-panel が queued にしました。
Decision
Routing decision: implementation_ready
Reason:
- Ticket is queued and explicitly decides to deprecate/remove
yoi.profile.extendin favor ofyoi.profile.importplus explicit Lua assignment. - Relation checks show no blocker; related launch-policy Ticket
00001KV11DHGZis not a dependency for this implementation. - Risk is bounded to Lua Profile API/resources/tests.
IntentPacket:
- Migrate builtin Profile resources away from
yoi.profile.extend, keepimport, and makeextendfail clearly or emit a deprecation diagnostic. Remove docs/tests that suggest scope replacement APIs.
Binding invariants:
- Do not solve concrete scope/delegation authority here; that belongs to
00001KV11DHGZ. - Do not add ambiguous replacement/clear API as part of
extend. - Builtin resources must use import + explicit Lua assignment.
Validation:
- focused profile resolution tests, resource/profile tests,
cargo fmt --check,git diff --check,cargo build -p yoi;nix build .#yoiif resource packaging is affected.
State changed
Ticket evidence, related records, orchestration plan, and clean workspace state were checked. No blockers remain; accept for implementation before worktree/spawn side effects.
Implementation report
Implemented removal/deprecation of yoi.profile.extend and migrated builtin role Profile resources to yoi.profile.import plus explicit Lua assignment.
Changes:
- yoi.profile.extend now fails with a removed-API diagnostic directing users to yoi.profile.import(...) plus assignment; the previous JSON deep-merge implementation was removed.
- Builtin role Lua profiles (companion/intake/orchestrator/coder/reviewer) import builtin:default, then assign each overridden field explicitly. Worker instruction overrides preserve imported worker defaults by assigning p.worker.instruction.
- Focused profile tests now cover explicit assignment, object replacement without hidden deep-merge retention, removed extend diagnostics, and role profile resolution/feature policy.
Validation:
- cargo fmt --check
- git diff --check
- cargo test -p manifest profile::tests:: -- --nocapture
- cargo build -p yoi
- nix build .#yoi (completed; dirty-tree warning expected before commit, result symlink removed)
Risks/notes:
- yoi.profile.extend remains present only as a failing diagnostic stub so callers receive an actionable migration error instead of a nil-call Lua error.
- Scope/delegation authority semantics were not expanded; this change only preserves existing builtin profile scope/delegation declarations while changing composition style.
Review: approve
承認します。
Evidence:
crates/manifest/src/profile.rsの Lua API はyoi.profile.import(...)を残し、yoi.profile.extend(...)は常にエラーにする互換診断スタブに変更されている。旧deep_merge_profile_jsonと hidden deep-merge composition は削除されており、診断文もyoi.profile.import(...)と explicit Lua assignment への移行を示している。- Builtin role profiles (
resources/profiles/{companion,intake,orchestrator,coder,reviewer}.lua) はyoi.profile.import("builtin:default")後に Lua の明示代入で必要フィールドだけを上書きしている。feature policy は各 role で全 key を明示し、worker instruction は table mutation で default reasoning 等を保持している。 - scope/delegation は既存 role の明示値を移植しており、profile composition の変更に留まっている。launch policy / authority semantics は別 Ticket
00001KV11DHGZの範囲として残され、今回の diff では拡張されていない。 - Tests cover import + explicit assignment, object replacement instead of deep merge, removed extend diagnostic, and builtin role resolution/policy (
profile::tests). - Resource embedding/packaging risk is low: changed files are existing
resources/profiles/*.lualoaded through the existing include table;cargo build -p yoipassed.
Validation performed:
git diff f709fc10..HEADinspected.cargo fmt --checkpassed.git diff --check f709fc10..HEADpassed.cargo test -p manifest profile::tests:: -- --nocapturepassed.cargo build -p yoipassed.
Not rerun:
nix build .#yoiwas not rerun in this reviewer scope because it would write outside the permittedtarget//Ticket-record areas unless using broader Nix/store/result-link authority. Coder reported it was run; cargo build validated resource embedding on this branch.
Risks / notes:
- Existing callers of
yoi.profile.extendnow fail intentionally; this is the requested break. The retained stub is a diagnostic compatibility trap, not a merge API.