diff --git a/.yoi/profiles/_base.lua b/.yoi/profiles/_base.lua index 54a02068..9bd0f114 100644 --- a/.yoi/profiles/_base.lua +++ b/.yoi/profiles/_base.lua @@ -15,6 +15,7 @@ return function(opts) worker = { reasoning = "high", + language = opts.language or "Japanese", }, model = { diff --git a/.yoi/profiles/coder.lua b/.yoi/profiles/coder.lua index e0762262..67be8f8f 100644 --- a/.yoi/profiles/coder.lua +++ b/.yoi/profiles/coder.lua @@ -5,5 +5,6 @@ return base { slug = "coder", description = "Coder role profile: GPT-5.5 with bundled default behavior", model_ref = "codex-oauth/gpt-5.5", + language = "Japanese", scope = scope.workspace_write(), } diff --git a/.yoi/profiles/companion.lua b/.yoi/profiles/companion.lua index 4744ea78..5fddc075 100644 --- a/.yoi/profiles/companion.lua +++ b/.yoi/profiles/companion.lua @@ -4,4 +4,5 @@ return base { slug = "companion", description = "Companion role profile: GPT-5.5 with bundled default behavior", model_ref = "codex-oauth/gpt-5.5", + language = "Japanese", } diff --git a/.yoi/profiles/intake.lua b/.yoi/profiles/intake.lua index 9327ffac..5561c5ad 100644 --- a/.yoi/profiles/intake.lua +++ b/.yoi/profiles/intake.lua @@ -4,4 +4,5 @@ return base { slug = "intake", description = "Intake role profile: GPT-5.5 with bundled default behavior", model_ref = "codex-oauth/gpt-5.5", + language = "Japanese", } diff --git a/.yoi/profiles/orchestrator.lua b/.yoi/profiles/orchestrator.lua index ac1d4968..b2cc373d 100644 --- a/.yoi/profiles/orchestrator.lua +++ b/.yoi/profiles/orchestrator.lua @@ -4,4 +4,5 @@ return base { slug = "orchestrator", description = "Orchestrator role profile: GPT-5.5 with bundled default behavior", model_ref = "codex-oauth/gpt-5.5", + language = "Japanese", } diff --git a/.yoi/profiles/reviewer.lua b/.yoi/profiles/reviewer.lua index 03852e9b..87732a99 100644 --- a/.yoi/profiles/reviewer.lua +++ b/.yoi/profiles/reviewer.lua @@ -4,4 +4,5 @@ return base { slug = "reviewer", description = "Reviewer role profile: GPT-5.5 with bundled default behavior", model_ref = "codex-oauth/gpt-5.5", + language = "Japanese", } diff --git a/.yoi/tickets/open/20260608-032200-panel-close-done-tickets/artifacts/.gitkeep b/.yoi/tickets/open/20260608-032200-panel-close-done-tickets/artifacts/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.yoi/tickets/open/20260608-032200-panel-close-done-tickets/item.md b/.yoi/tickets/open/20260608-032200-panel-close-done-tickets/item.md new file mode 100644 index 00000000..14c29a1c --- /dev/null +++ b/.yoi/tickets/open/20260608-032200-panel-close-done-tickets/item.md @@ -0,0 +1,76 @@ +--- +id: '20260608-032200-panel-close-done-tickets' +slug: 'panel-close-done-tickets' +title: 'Close done Tickets from workspace panel' +status: 'open' +kind: 'task' +priority: 'P2' +labels: ['tui', 'panel', 'ticket', 'close', 'workflow-state'] +workflow_state: 'intake' +created_at: '2026-06-08T03:22:00Z' +updated_at: '2026-06-08T03:22:00Z' +assignee: null +legacy_ticket: null +--- + +## Background + +Panel currently derives `NextUserAction::Close` for Tickets whose `workflow_state` is `done`, but the action is a safe no-op: + +```text +Close for Ticket requires explicit resolution text; no close was recorded. +``` + +This leaves Tickets in an awkward state: + +```text +status: open +workflow_state: done +``` + +The Ticket backend `close` operation is more than a raw directory move: it moves the Ticket to `closed/`, updates `item.md`, writes `resolution.md`, and records a close/resolution event. However, when a Ticket is already `workflow_state: done`, the completion judgment has already happened. Panel does not need to launch an LLM worker just to produce a resolution. + +## Goal + +Implement Panel `Close` action for `workflow_state: done` Tickets by calling the Ticket backend close operation with a deterministic generated resolution. + +## Requirements + +- Implement `NextUserAction::Close` dispatch in the TUI/Panel path. +- Only auto-close when the Ticket is safe to close, at minimum: + - local status is `open`; + - `workflow_state == done`; + - `attention_required` is not set; + - `action_required` is not set or otherwise not blocking close; + - `resolution.md` does not already exist. +- Generate a deterministic resolution without invoking an LLM worker. +- Resolution should be concise and factual, e.g.: + +```md +Closed from workspace panel. + +The Ticket had already reached `workflow_state: done`. +No implementation or workflow-state changes were started by this close action. +See `thread.md` for implementation, review, merge, validation, and state-change records. +``` + +- Call the existing Ticket backend close path/tooling rather than manually moving files. +- After close, refresh Panel state so the Ticket disappears from open rows / appears in closed history as appropriate. +- If the Ticket is not safe to close, show a bounded diagnostic explaining the blocker instead of doing nothing. +- Do not close Tickets whose workflow state is not `done`. +- Do not launch Orchestrator/Companion/worker solely to generate resolution text. +- Do not auto-commit the close in this ticket unless the separate commit-policy work decides that behavior. + +## Design notes + +This is primarily a TUI/Panel feature. The Ticket backend already exposes a close operation requiring resolution text; the Panel should supply a deterministic generated resolution for already-done Tickets and invoke that backend operation. + +## Acceptance criteria + +- Pressing empty `Enter` on a `workflow_state: done` open Ticket in Panel closes it through the Ticket backend. +- The closed Ticket has `resolution.md` with deterministic generated text. +- The close is recorded in the Ticket thread/status according to existing backend behavior. +- Unsafe close attempts produce clear diagnostics and do not mutate the Ticket. +- Panel refreshes after close. +- Tests cover successful close, blocked close, and generated resolution content. +- Relevant TUI/Ticket tests, `cargo fmt --check`, `git diff --check`, and `target/debug/yoi ticket doctor` pass. diff --git a/.yoi/tickets/open/20260608-032200-panel-close-done-tickets/thread.md b/.yoi/tickets/open/20260608-032200-panel-close-done-tickets/thread.md new file mode 100644 index 00000000..ea8fe7bb --- /dev/null +++ b/.yoi/tickets/open/20260608-032200-panel-close-done-tickets/thread.md @@ -0,0 +1,7 @@ + + +## Created + +Created by LocalTicketBackend create. + +--- diff --git a/.yoi/tickets/open/20260608-032911-separate-ticket-record-language-from-worker-language/artifacts/.gitkeep b/.yoi/tickets/open/20260608-032911-separate-ticket-record-language-from-worker-language/artifacts/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.yoi/tickets/open/20260608-032911-separate-ticket-record-language-from-worker-language/item.md b/.yoi/tickets/open/20260608-032911-separate-ticket-record-language-from-worker-language/item.md new file mode 100644 index 00000000..469a0275 --- /dev/null +++ b/.yoi/tickets/open/20260608-032911-separate-ticket-record-language-from-worker-language/item.md @@ -0,0 +1,74 @@ +--- +id: '20260608-032911-separate-ticket-record-language-from-worker-language' +slug: 'separate-ticket-record-language-from-worker-language' +title: 'Separate Ticket record language from worker response language' +status: 'open' +kind: 'task' +priority: 'P2' +labels: ['ticket', 'language', 'config', 'profile', 'workflow'] +workflow_state: 'intake' +created_at: '2026-06-08T03:29:11Z' +updated_at: '2026-06-08T03:29:11Z' +assignee: null +legacy_ticket: null +--- + +## Background + +Profiles/Manifests currently provide `worker.language`, which controls normal Pod prose responses. This is not the same as the language used for durable Ticket records. + +Ticket records are authored by multiple paths: + +- LLM role Pods writing Ticket comments/reviews/decisions; +- typed Ticket tools generating state-change/intake/close events; +- Panel/CLI generated notices/resolutions; +- scaffold/default Ticket bodies. + +This project wants to distinguish: + +- response language: how a Pod replies to the user in conversation; +- Ticket record language: the language used for durable Ticket `item.md`, `thread.md`, `resolution.md`, and generated Ticket event bodies. + +Currently `.yoi/ticket.config.toml` has no language setting. Role profiles can set `worker.language = "Japanese"`, but that does not provide a backend/tool-level policy for machine-generated Ticket text. + +## Goal + +Add an explicit Ticket record language configuration separate from Pod response language. + +## Requirements + +- Add a Ticket config setting for durable Ticket record language. + - Candidate shape: + +```toml +[ticket] +language = "Japanese" +``` + + - Avoid overloading `[worker].language` or Profile settings for this purpose. +- Define the boundary clearly: + - `worker.language`: conversation/prose responses by a Pod. + - `ticket.language`: durable Ticket records and generated Ticket event/resolution/scaffold text. +- Make typed Ticket tool/backend generated text consult `ticket.language` where practical. +- Ensure LLM role prompts can receive or reference Ticket record language so comments/reviews/decisions use the configured Ticket language even if the Pod response language differs. +- Preserve existing behavior when `ticket.language` is absent, using the current/default language policy. +- Update `.yoi/ticket.config.toml` scaffold and parser. +- Update project `.yoi/ticket.config.toml` to set the desired Ticket record language. +- Avoid translating protocol literals, file paths, commands, logs, identifiers, or quoted external text merely because Ticket language is set. + +## Design questions + +- Should the config key be `[ticket].language`, `[records].language`, or `[backend].language`? + - Prefer `[ticket].language` because this is record-generation policy, not storage backend mechanics. +- Should tool-generated default bodies/resolutions be localized immediately, or should this ticket only thread the config through and update the most visible generation paths? +- How should existing Tickets be handled? Do not rewrite existing records unless explicitly requested. + +## Acceptance criteria + +- Ticket config can specify a Ticket record language independently of Profile/worker language. +- Role launch prompts/tool instructions expose the Ticket record language to Intake/Orchestrator/Coder/Reviewer where they write Ticket records. +- Typed Ticket-generated events/resolutions/scaffold have a clear policy for using the configured language. +- Absence of `ticket.language` preserves current behavior. +- Existing Tickets are not bulk-translated or rewritten. +- Tests cover config parsing/scaffold/default behavior and at least one generation/role prompt path. +- `target/debug/yoi ticket doctor`, focused tests, `cargo fmt --check`, and `git diff --check` pass. diff --git a/.yoi/tickets/open/20260608-032911-separate-ticket-record-language-from-worker-language/thread.md b/.yoi/tickets/open/20260608-032911-separate-ticket-record-language-from-worker-language/thread.md new file mode 100644 index 00000000..cba72eb4 --- /dev/null +++ b/.yoi/tickets/open/20260608-032911-separate-ticket-record-language-from-worker-language/thread.md @@ -0,0 +1,7 @@ + + +## Created + +Created by LocalTicketBackend create. + +---