refactor: remove repository-local yoi authority

This commit is contained in:
2026-09-22 22:52:41 +09:00
parent 043cb7bf22
commit 5fb3cb20cd
45 changed files with 487 additions and 9151 deletions
+11 -9
View File
@@ -1,15 +1,17 @@
# Generated memory records
# Workspace Memory authority
Yoi keeps generated memory under `.yoi/memory/` for durable, low-volume context:
Generated Memory is durable Workspace context owned by the Workspace Server control plane. Runtime Workers query and mutate it through typed Workspace API operations; they do not read or write repository-local paths.
- `summary.md` is optional resident context.
- `decisions/*.md` capture durable decisions and rationale.
- `requests/*.md` capture durable user preferences or standing requests.
The active Memory document and staging/audit lifecycle are stored by the Server-owned backend. Worker-side `memory` code contains only shared schema, extraction, audit, and transport types needed to construct those operations.
Memory records are not workspace record authority for exact implementation state. Use tickets, objectives, repository files, git history, and session logs for exact current facts.
Repository or ancestor `.yoi/memory`, `.yoi/knowledge`, and malformed marker trees are ignored. There is no cwd/ancestor discovery, dual read, startup import, or automatic migration. The removed `yoi memory lint` command is intentionally not a compatibility surface; invoking `yoi memory ...` is an unknown command.
## Historical Knowledge records
Memory remains supporting context rather than implementation authority. Use Tickets, Objectives, repository files, Git history, and append-only session records for exact current facts.
Older workspaces may contain `.yoi/knowledge/`. Knowledge is no longer an active supported feature or workspace record authority. Current memory tooling ignores it; archive or inspect those files manually if needed.
## Upgrade guidance
Future Agent Skills are intentionally separate and are not implemented by this design note.
Old repository-local Memory data is not imported automatically. Before upgrading from a version that used `.yoi/memory`, explicitly export any data that must be retained with that old version and import it into the Workspace-backed product surface available to the deployment. Stale files may be archived or deleted after verification.
## Preserved filesystem boundaries
This removal does not affect repository checkouts, Git metadata, Runtime-owned Workdirs/session logs/artifacts, Server data directories, or XDG client/server configuration. It removes only ambient repository-local Memory authority.
+3 -3
View File
@@ -6,7 +6,7 @@ This decision records the layout policy for Ticket `00001KTTB479X`.
## Roots
- `role_workspace_root`: the launched role runtime workspace root and Ticket backend context.
- `role_workspace_root`: the launched role Runtime's explicit execution/workdir root. Ticket authority remains the Workspace Server control-plane database reached through the Workspace API.
- `original_workspace_root`: the repository root from which implementation worktrees should be created.
- `implementation_worktree_root`: `<original_workspace_root>/.worktree`.
- `merge_target_workspace_root`: the workspace/branch where merge-completion validates and merges.
@@ -15,9 +15,9 @@ When these roots differ, implementation worktrees must be created under `impleme
## Policy
- The filesystem Ticket backend remains authoritative for project records; this design does not introduce a Git-external Ticket store.
- Workspace Server Ticket records remain authoritative; none of these filesystem roots selects or hosts a Ticket backend.
- Main-workspace draft Tickets are not an implicit Orchestrator queue. Queue acceptance still requires explicit Ticket state and routing checks.
- Implementation branches should not include unrelated Orchestrator Ticket churn. Orchestration progress stays in the Orchestrator workspace/Ticket backend; child implementation worktrees contain implementation diffs and branch-local artifacts only when needed.
- Implementation branches should not include unrelated Orchestrator bookkeeping. Orchestration progress stays in the Workspace Server Ticket/event record; child implementation worktrees contain implementation diffs and branch-local artifacts only when needed.
- Prompt and workflow guidance must treat merge-ready dossier as a checkpoint. If reviewer approval, clean/safe target workspace, and standing/user merge authority are present, Orchestrator should continue through merge, validation, Ticket close, and cleanup instead of stopping solely because a dossier exists.
## Implemented in this branch
+2 -2
View File
@@ -6,7 +6,7 @@ That rule shapes the crate split. The runtime can restart, attach, compact, or d
## Core layers
- `yoi` owns the product CLI and top-level command shape. It is the façade that wires profile selection, memory linting, and normal TUI launch.
- `yoi` owns the product CLI and top-level command shape. It is the façade that wires connection selection, product commands, and normal TUI launch.
- `worker` turns a `Engine` into a named runtime entity with scope, session persistence, protocol handling, tools, and Worker metadata integration.
- `agen` owns model-facing turns: history append, retries, continuation, pruning/compaction mechanics, tool loops, and provider-independent callbacks.
- `session-store` owns replayable append-only conversation/session logs.
@@ -16,7 +16,7 @@ That rule shapes the crate split. The runtime can restart, attach, compact, or d
- `client` contains reusable Backend Workspace/Runtime clients plus the shared `Target` boundary. Its normal targets are exactly Standalone and Backend; it is not a subprocess launcher or repository-local product backend.
- `manifest` resolves Profiles, Manifests, model/provider references, scopes, prompts, and tool permission policy into a runtime contract.
- `tools` implements built-in tools with bounded output and policy-aware execution.
- `memory` owns generated memory summary/decision/request records, linting, staging, and audit observations.
- `memory` owns shared Memory domain, extraction, audit-event, and Workspace API transport types. Persistence and lifecycle execution belong to the Workspace Server control plane.
- `workspace-server` is the local Workspace control-plane seam. It can project Tickets, Workers, lifecycle, usage, and orchestration events, but browser/API operations must stay on opaque backend identities instead of raw local paths, sockets, Worker names, or session files.
- `tui` is a UI over either one in-process Standalone session or Backend Workspace/Runtime Worker authority; it should not invent a local Worker catalog or durable product state.
+13 -78
View File
@@ -1,19 +1,19 @@
# Tickets and development workflow
Yoi project work is tracked through Tickets. For normal use, interact with Tickets through `yoi panel`, Ticket tools, the `yoi ticket ...` CLI, and typed role surfaces. Git history plus Ticket files remain the authoritative state-transition record behind those interfaces.
Yoi project work is tracked through Tickets. For normal use, interact with Tickets through `yoi panel`, Ticket tools, the `yoi ticket ...` CLI, and typed role surfaces. Workspace Server control-plane records plus the append-only Ticket event and Merge Request evidence streams are authoritative.
The current local backend stores each Ticket in the flat `.yoi/tickets/<ticket-id>/` layout. The directory name is the canonical opaque Ticket id: a fixed-width Crockford base32 Unix epoch millisecond timestamp. Slugs and frontmatter `id`/`slug` fields are not current-state authority. That storage detail matters for maintainers and backend compatibility, but it is not the primary user-facing workflow.
Ticket and Objective records are stored in the Workspace Server database. Repository-local `.yoi/tickets`, `.yoi/objectives`, and config files are ignored legacy input, not a debugging or compatibility backend.
Do not treat ad-hoc chat summaries, memory records, or Worker notifications as the final source of project state. Notifications are hints to inspect concrete state, not proof of completion.
## Concepts
- `Ticket`: durable project/orchestration record. It contains requirements, decisions, plans, implementation reports, reviews, artifacts, and resolution history.
- `Objective`: first-class medium-term goal record. It stores goal, motivation/background, strategy/design direction, success criteria/exit conditions, decision context, current Objective lifecycle, and canonical Ticket links under `.yoi/objectives/<objective-id>/item.md`. Objective context is judgment/background context; it is not implementation authority and does not replace reading each Ticket body/thread/artifacts.
- `Objective`: first-class medium-term goal record stored by the Workspace Server. It stores goal, motivation/background, strategy/design direction, success criteria/exit conditions, decision context, current Objective lifecycle, and canonical Ticket links. Objective context is judgment/background context; it is not implementation authority and does not replace reading each Ticket body, thread, and evidence.
- `Task`: session-local progress tracking inside a Worker. It is not the project record.
- `Assignment`: a concrete delegation from an Orchestrator to a coder/reviewer Worker or task-specific helper Worker.
- `IntentPacket`: the short implementation/review contract derived from a Ticket and handed to an Assignment.
- `LocalTicketBackend`: the current `.yoi/tickets/` markdown/thread/artifacts storage backend.
- `Ticket backend`: the Workspace Server control-plane database exposed through typed Workspace APIs.
- `Ticket relation`: durable project-level Ticket-to-Ticket metadata stored as forward canonical-id relations (`depends_on`, `blocks`, `related`, `supersedes`, `duplicate_of`). Inverse views such as `blocked_by` are derived, not stored.
A Ticket may represent a feature, bug, cleanup, design decision, investigation, workflow change, release task, or orchestration task. The common requirement is that the Ticket is a concrete work item that can be implemented, reviewed, validated, and closed on its own terms.
@@ -27,7 +27,7 @@ Use the highest-level interface that matches the work:
- Inside Workers, use typed Ticket tools for Ticket records and typed Merge Request tools for immutable implementation/review/completion evidence.
- For multi-step work, follow the typed Ticket role surfaces and recorded Ticket lifecycle gates.
Maintainers can inspect the local `.yoi/tickets/` files directly when debugging storage, but normal user instructions should go through `yoi panel`, Ticket tools, or `yoi ticket ...`.
Maintainers inspect Ticket state through the authenticated Workspace API, Server administration surfaces, and database diagnostics. Repository-local Ticket files are not storage authority.
## Ticket tools inside Workers
@@ -45,7 +45,7 @@ Workers with the Ticket and operation-specific Merge Request built-in features c
Profile-visible Ticket catalogs are intentionally smaller than the former broad read catalog: Workspace authoring exposes 9 tools instead of 13, workflow exposes 10 instead of 12, and review exposes only `QueryTicket` plus `ShowTicket` (2 instead of 6). The `QueryTicket` schema is regression-guarded below 8 KiB while consolidating relation/evidence/attention discovery; diagnostics are not projected into normal profiles, while specialized orchestration-plan commands remain visible only to workflow roles that need their distinct semantics.
These tools operate through the typed Ticket backend. They are not arbitrary filesystem write permission to `.yoi/tickets/`.
These tools operate through the typed Workspace Ticket API. They do not grant arbitrary filesystem access and never select repository-local Ticket storage.
Relation tools are for non-hierarchical project metadata only. Use canonical opaque Ticket ids, store forward relations only, and keep runtime execution planning (capacity, ordering decisions, do-not-parallelize notes, Worker/session/worktree ownership) in OrchestrationPlan or session-local records instead of relation metadata. Unresolved `depends_on` and incoming unresolved `blocks` are queue/acceptance blockers; `related` is not blocking, and `supersedes` / `duplicate_of` are diagnostics rather than automatic lifecycle transitions.
@@ -60,51 +60,11 @@ Do not bypass Ticket lifecycle gates just because Ticket tools are available. Ti
## Objective records
Objectives are lightweight medium-term project records, not Tickets, Ticket relations, OrchestrationPlan execution records, or Worker/session claims. Use them when a goal spans several concrete Tickets and the durable motivation, design direction, success criteria, or decision context would otherwise be repeated or lost.
Objectives are Workspace Server control-plane records, not files in a checkout. Use typed Objective tools or `yoi objective ...`; both resolve the selected Backend/Workspace through the shared client target and call the Workspace API.
The local Objective surface stores records under:
Objective-to-Ticket links are context links only: they are not dependency, blocking, ordering, ownership, or scheduling relations. Objective lifecycle does not drive Ticket state or authorize implementation. A role reading Objective context must still inspect each Ticket and its current Merge Request evidence.
```text
.yoi/objectives/<objective-id>
item.md
```
`<objective-id>` is the canonical opaque path-derived id: a fixed-width Crockford base32 Unix epoch millisecond timestamp. Do not treat Objective titles or slug words as link authority.
`item.md` uses YAML frontmatter plus Markdown body:
```yaml
---
title: "Improve orchestration evidence"
state: "active" # active|paused|done|archived
created_at: "2026-06-09T00:00:00Z"
updated_at: "2026-06-09T00:00:00Z"
linked_tickets: ["00001KTKMS0VG"]
---
```
The Markdown body should include these sections:
- `## Goal`
- `## Motivation / background`
- `## Strategy / design direction`
- `## Success criteria / exit conditions`
- `## Decision context`
Linked Tickets must be canonical opaque Ticket ids that exist in the configured Ticket backend root. Objective-to-Ticket links are context links only: they are not dependency, blocking, ordering, ownership, or scheduling relations. Use typed Ticket relations for Ticket-to-Ticket dependency/blocking/related metadata, OrchestrationPlan records for routing/execution plans, and Worker/session claims for runtime ownership hints.
Objective lifecycle is only Objective lifecycle. `active`, `paused`, `done`, and `archived` do not drive Ticket `state`, do not authorize implementation, and do not close linked Tickets. A role reading Objective context must still inspect each Ticket body, thread, artifacts, explicit Ticket relations, and OrchestrationPlan records before acting.
The maintainer CLI is:
```sh
yoi objective create --title "..." [--ticket <ticket-id> ...]
yoi objective list [--state active|paused|done|archived|all]
yoi objective show <objective-id>
yoi objective doctor
```
The first version intentionally does not implement roadmap scheduling, milestones, OKRs, graph solving, Objective-mandatory Ticket creation, Objective thread/artifact history, or broad panel UX. Future UX can surface Objective context around Tickets as long as it remains background context and never substitutes for reading the Ticket.
Repository-local `.yoi/objectives` trees are ignored. There is no automatic import or cwd/ancestor fallback.
## Ticket configuration
@@ -268,40 +228,15 @@ A useful Ticket states:
- reviews;
- final resolution when closed.
Keep long research dumps out of the item body. Put necessary artifacts under the Ticket's `artifacts/` directory and summarize the conclusion in the thread.
Keep long research dumps out of the item body. Attach necessary bounded artifacts through the Ticket evidence surface and summarize the conclusion in the thread.
Do not store secrets, credentials, private prompt contents, or raw logs containing secrets in Ticket bodies, thread entries, artifacts, diagnostics, or model-visible prompts.
## Backend/maintainer CLI: `yoi ticket`
## Backend CLI: `yoi ticket`
The product CLI exposes the typed Ticket backend for repository maintenance and validation. It operates on the configured `.yoi/tickets/` storage and is the preferred command-line surface when editing Tickets outside a Worker.
The product CLI resolves an explicit or configured Backend target and performs Ticket operations through the Workspace API. It does not open a repository-local backend. Use command help for the current typed command surface.
```sh
yoi ticket create --title "..." [--priority P2]
yoi ticket list [--state planning|ready|queued|inprogress|done|closed|all] [--limit n]
yoi ticket show <id>
yoi ticket comment <id> [--role comment|plan|decision|implementation_report] [--file path]
yoi ticket review <id> --approve|--request-changes [--file path]
yoi ticket state <id> <planning|ready|queued|inprogress|done>
yoi ticket close <id> [--resolution text|--file path]
yoi ticket doctor
```
`yoi ticket list` is a capped overview/selection command. It should remain readable for humans and safe for model context: use it to find a canonical id, then use `yoi ticket show <id>` before routing, closing, planning, or implementation decisions.
`yoi ticket state` records current lifecycle transitions among active states. Closing must use `yoi ticket close` so the backend writes the required `resolution.md` and passes `yoi ticket doctor`; `done` and `closed` remain distinct states.
The current LocalTicketBackend stores records under:
```text
.yoi/tickets/<ticket-id>
item.md
thread.md
artifacts/
resolution.md # closed Tickets only
```
Backend integrations must preserve this format until an explicit migration changes it. `thread.md` is an append-only typed event log: existing events such as `create`, `comment`, `plan`, `decision`, `implementation_report`, `review`, `state_changed`, and `close` remain valid, while `state_changed` records durable transition metadata (`from`, `to`, `reason`, optional `field`, plus `author` and `at`) and `intake_summary` records the bounded Intake outcome body. Thread events are audit history, not current-state authority; current state belongs in `item.md` frontmatter or the owning backend record. The repository-root `work-items/` path is no longer a live mutable backend; do not recreate it for Ticket records. Human users should prefer `yoi panel`, Ticket tools, or `yoi ticket ...` when working directly with repository records.
Legacy `ticket init` and `ticket import-local` workflows are unsupported. No automatic migration reads old `.yoi/tickets` trees; export data with an older version before upgrading if it must be retained, then import it through an explicit supported Workspace surface.
## Validation
@@ -0,0 +1,14 @@
# Repository-local `.yoi` authority removal
This release removes the remaining production readers, writers, discovery helpers, fallbacks, and import paths that treated a repository-local `.yoi` tree as product authority.
Removed surfaces include:
- Ticket filesystem config loading, `LocalTicketBackend`, and local-to-SQLite import helpers;
- Worker Ticket feature constructors backed by local paths;
- Memory repository layout/discovery, local resident/query/staging/audit/usage executors, and `yoi memory lint`;
- the Runtime helper that derived its store from `<workspace>/.yoi/runtime-store`.
Workspace identity, metadata, Ticket, Objective, Memory, and launch configuration remain owned by the Workspace Server control-plane database and typed Workspace APIs. Client routing remains in XDG client configuration. Runtime-owned Workdirs, session logs, artifacts, Server data directories, repository/Git files, explicit Plugin package files, and the legacy home-directory secret-store boundary are unchanged.
There is no automatic migration or compatibility fallback. Before upgrading from a version that stored active Ticket or Memory data in a repository `.yoi` tree, explicitly export data with the old version and import it through a supported Workspace-backed surface. Stale or malformed repository/ancestor `.yoi` trees are ignored by normal operation and may be archived or removed after verification.
@@ -0,0 +1,51 @@
# T-452 final repository-local `.yoi` authority audit
Date: 2026-09-22
Objective: O-12
Ticket: T-452
## Baseline and method
The implementation branch was created from `develop` at `043cb7bf22bd59d1d553e3f5a7c86c20502fad30` after confirming that ref was the then-current provider-resolved `origin/develop`. This audit follows normal entrypoints through constructors and typed backends to their I/O boundary. A raw `.yoi` string search was used only to enumerate candidates; strings in comments, negative regression fixtures, explicit artifacts, and preserved storage boundaries are not treated as authority by themselves.
The final pre-review pass must refresh from `develop` after T-629 is integrated. T-629 owns conversion of the existing panel E2E setup; this change neither restores nor duplicates that legacy fixture.
## Reachability and disposition
| Surface | Entry point and pre-change path | Disposition |
| --- | --- | --- |
| Ticket config | `TicketConfig::load_workspace` read `<workspace>/.yoi/workspace.toml`, fell back to `.yoi/ticket.config.toml`, and defaulted to `.yoi/tickets`. | Removed the filesystem loader, backend path/provider types, fallback parser, and path resolution. `ticket::config` now contains only filesystem-independent fixed-role domain types. |
| Ticket provider | Public `LocalTicketBackend` performed Ticket tree reads/writes. `SqliteTicketBackend::import_from_local_backend` converted that tree into SQLite. | Removed both production providers/helpers and their filesystem-only tests. SQLite fixtures now seed `typed_tickets`/events directly. Deliberately stale Ticket/Objective trees remain only as ignored-input regressions. |
| Worker Ticket tools | `TicketFeatureBackend::Local`, `TicketFeature::for_workspace[_with_access]`, and local constructors could install filesystem-backed tools even though the normal controller already selected a Workspace client. | Removed the local variant and constructors. The feature now accepts only an injected `Arc<dyn WorkspaceClient>` and constructs `WorkspaceHttpTicketBackend`; there is no provider-selection enum or filesystem path parameter. |
| Memory CLI | `yoi memory lint` -> `memory_lint::run` -> cwd/`--workspace` -> `WorkspaceLayout` -> filesystem linter. | Removed the mode, parser/help branch, module, and CLI dependency. Old invocations fail as unknown before target/cwd resolution and do not read or mutate malformed legacy input. No replacement Memory UX or compatibility shim was added. |
| Memory provider | `WorkspaceLayout::resolve` searched cwd/ancestors and supplied `.yoi/memory` paths to query/resident, staging, consolidation, audit, usage, scope, and lint implementations. `execute_memory_backend_operation` dispatched operations to that layout. | Removed layout/discovery, local executor, resident/scope/usage writers, extraction/consolidation staging files, filesystem audit implementation, and path-scanning linter modules. Kept Backend operation DTOs, extraction payload/tool contracts, audit event DTOs, provenance/frontmatter schema helpers, and lint-common slug types because they are filesystem-independent shared domain/API types. Workspace Server SQLite authority remains the Memory persistence executor. |
| Runtime store | Public `WorkerRuntimeExecutionBackend::from_workspace` derived `<workspace>/.yoi/runtime-store`. | Removed. Runtime callers continue to pass explicit Runtime-owned store/config paths; no repository fallback was introduced. |
| Workspace/client/bootstrap | Normal `yoi init`, client target resolution, Workspace catalog/metadata, Server bootstrap, and repository mapping were already cut over by T-468. | Preserved. Existing root/ancestor stale-marker and clean-init tests continue to assert Server DB/API plus XDG client routing, with no repository write. |
| Profile/Skill/Prompt | Workspace projections were already sourced from the Server virtual config tree; direct Worker startup uses explicit manifest/builtin authority. | Preserved. Existing malformed local profile/prompt/skill fixtures are negative tests. A clean direct Worker-startup regression now verifies that manifest resolution does not create `.yoi`. |
| Plugin | T-603 already removed ambient `.yoi/plugins` discovery. | Preserved the source assertions and explicit `.yoi-plugin` offline package operations. No install/runtime fallback was added. |
| Objective | Worker Objective tools already require Workspace API authority; Workspace Server stores Objective rows in SQLite. | Preserved. Filesystem-only Objective fixtures are ignored-input regressions, not import setup. |
| Web/TUI | Both consume Workspace HTTP/client models and do not construct repository Ticket/Memory backends. | Preserved. Their checks validate the current typed API/routing surfaces; T-629 separately owns the panel E2E fixture modernization. |
## Regression evidence added or strengthened
- Source assertions reject the concrete production provider/constructor chain rather than banning every `.yoi` string: Ticket config/provider/import, Worker local Ticket feature, Memory layout/executor/staging entrypoints (including every compiled extraction implementation module), Runtime `from_workspace`, and CLI `memory_lint` mode.
- `TicketFeature` has no repository/cwd input: installation accepts only an authority-scoped Workspace client and access policy. A regression verifies that separately present malformed repository-root Ticket input and malformed ancestor Workspace input remain byte-for-byte unchanged while the Workspace tool surface installs.
- The removed Memory CLI is unknown with bare, `lint`, help, and legacy `--workspace` forms; a malformed `.yoi/memory` fixture remains byte-for-byte unchanged.
- Direct Worker manifest resolution against a clean explicit workspace does not create `.yoi`. A Runtime integration regression additionally creates a Worker from a clean Git repository, executes a turn, stops/restores the Worker, and verifies that launch and restore never create repository-local `.yoi` authority.
- Ticket tool mutation uses a direct SQLite backend and asserts `tickets.db` is written while `.yoi`/`tickets` are not.
- Workspace Server authority seeds SQLite Ticket/Objectives directly, proves filesystem-only records are ignored, and proves legacy Memory staging cannot enter the Backend consolidation backlog.
## Remaining `.yoi` classifications
The post-change source inventory contains the following intentional classes:
1. **Negative regression input or assertions:** stale/malformed Workspace, Ticket, Objective, Memory, Profile, Skill, Prompt, and Plugin trees; assertions that clean operation creates no `.yoi`; leak-prevention fixtures.
2. **Preserved runtime/server boundaries:** Runtime-owned Workdirs and run artifacts, explicit Server data/config directories, session-store compatibility for the legacy home-directory secret/session boundary, and generated ignore files that prevent execution artifacts from entering Git.
3. **Explicit artifacts:** repository/Git files selected by the user and `.yoi-plugin` package paths passed directly to offline `new`/`check`/`pack` commands.
4. **Documentation/history:** current guidance describing removal and historical reports retained as historical evidence.
None of these classes performs cwd/ancestor authority discovery, automatic import, dual read, or repository-local fallback. The repository checkout and Git metadata remain ordinary filesystem inputs; removing filesystem use in general is outside T-452.
## Upgrade contract
There is no automatic migration, startup import, compatibility reader, or delete pass. Deployments that still need legacy repository-local Ticket or Memory data must export it with the old version before upgrading and import it through a supported Workspace-backed surface. Stale trees are ignored and can be archived or removed only after operator verification.