ticket: use base32 project record ids

This commit is contained in:
2026-06-09 22:10:47 +09:00
parent 0803bc3725
commit 4203988d74
798 changed files with 477 additions and 105 deletions
@@ -0,0 +1,185 @@
# Ticket definition and API shape
## Definition
In yoi, a Ticket is the durable orchestration record shared by humans, Intake Pods, Orchestrator Pods, coder Pods, and reviewer Pods.
Short definition:
> A Ticket is a durable coordination contract that preserves agreed intent, requirements, readiness, decisions, evidence, review results, and resolution history so Pod groups can route, delegate, implement, verify, and complete work without losing the original intent.
A local markdown ticket, GitHub Issue, Linear issue, Jira issue, or another tracker record can be a backend representation of a Ticket, but none of those storage representations define the concept.
The current local backend is the repository's `work-items/` directory managed by `tickets.sh`. That path remains unchanged for now.
## Roles served by a Ticket
A Ticket is simultaneously:
- Intent anchor: preserves what the user and Intake agreed to.
- Requirements contract: states observable requirements, acceptance criteria, non-goals, and escalation conditions.
- Routing unit: lets Orchestrator decide between requirements sync, preflight, spike, implementation, review, blocked/action-required, pending, or close.
- Delegation source: lets Orchestrator derive an `IntentPacket` for a concrete Pod `Assignment`.
- Review contract: gives reviewer Pods an explicit basis for approval or request-changes.
- Evidence ledger: records plans, decisions, implementation reports, validation, review, artifacts, commits, branches, and resolution.
- Backend-neutral record: local files are the first backend, not the product concept.
## Relationship to other terms
- `Task`: session-local progress tracking inside a Pod/session. Smaller and more ephemeral than a Ticket.
- `Ticket`: durable project/orchestration record.
- `Assignment`: concrete delegation from Orchestrator to a coder/reviewer/investigator Pod.
- `IntentPacket`: concise implementation/review contract extracted from a Ticket and passed to an Assignment.
- `TicketBackend`: backend abstraction for Ticket storage/mutation.
- `LocalTicketBackend`: current local file backend over `work-items/`.
## Conceptual shape
The Rust model should use a thin typed envelope around Markdown/freeform body content.
Typed enough for machines:
- id / slug / title;
- kind / priority / labels;
- status;
- readiness;
- needs-preflight;
- risk flags;
- action-required state;
- event kind;
- review result;
- artifact references;
- branch/commit/Pod references where useful.
Flexible enough for humans/LLMs:
- background;
- requirements;
- acceptance criteria;
- rationale;
- design notes;
- plan;
- implementation report;
- review body;
- resolution.
## Candidate types
```rust
struct Ticket {
id: TicketId,
slug: TicketSlug,
title: String,
meta: TicketMeta,
body: TicketDocument,
events: Vec<TicketEvent>,
artifacts: Vec<TicketArtifactRef>,
}
struct TicketSummary {
id: TicketId,
slug: TicketSlug,
title: String,
status: TicketStatus,
kind: TicketKind,
priority: TicketPriority,
readiness: TicketReadiness,
needs_preflight: bool,
action_required: Option<ActionRequired>,
}
enum TicketStatus {
Open,
Pending,
Closed,
Other(String),
}
enum TicketReadiness {
Unspecified,
RequirementsSyncNeeded,
SpikeNeeded,
ImplementationReady,
Blocked,
Other(String),
}
enum TicketEventKind {
Comment,
Plan,
Decision,
ImplementationReport,
Review,
StatusChanged,
Closed,
Other(String),
}
struct TicketEvent {
kind: TicketEventKind,
body: MarkdownText,
refs: Vec<TicketRef>,
}
```
## Candidate backend trait
```rust
trait TicketBackend {
fn list(&self, filter: TicketFilter) -> Result<Vec<TicketSummary>>;
fn show(&self, id: TicketIdOrSlug) -> Result<Ticket>;
fn create(&self, input: NewTicket) -> Result<TicketRef>;
fn add_event(&self, id: TicketIdOrSlug, event: NewTicketEvent) -> Result<()>;
fn review(&self, id: TicketIdOrSlug, review: TicketReview) -> Result<()>;
fn set_status(&self, id: TicketIdOrSlug, status: TicketStatus) -> Result<()>;
fn close(&self, id: TicketIdOrSlug, resolution: MarkdownText) -> Result<()>;
fn doctor(&self) -> Result<TicketDoctorReport>;
}
```
The trait should remain backend-shaped and should not bake local file paths into the concept. Local paths belong in `LocalTicketBackend` configuration and implementation.
## Authority boundary
Ticket authority is separate from ordinary source/worktree filesystem scope.
Filesystem scope protects implementation areas and source edits. Ticket management is shared project coordination state and should be mediated through typed Ticket operations, backend locks/conflict handling, and audit/history records rather than delegated arbitrary write access.
This does not imply unlimited Ticket access. Ticket tools should be granted explicitly and limited to configured Ticket backends and operations.
## Backend layering
```text
Ticket API / TicketBackend
├─ LocalTicketBackend -> current work-items/ directory
├─ GitHubTicketBackend -> possible future backend
├─ LinearTicketBackend -> possible future backend
└─ McpTicketBackend -> possible future bridge
```
Local files are the first backend because they are already the authoritative project record in this repository. External tracker support is not part of the MVP.
## Validation/linting direction
Prefer a Ticket linter/policy layer over strict structural enforcement for all body content.
The code should enforce mechanical consistency and safe mutation:
- required frontmatter fields;
- status directory consistency;
- id/slug uniqueness;
- thread event parseability;
- review/result shape;
- resolution existence for closed tickets;
- artifact path containment;
- lock/conflict behavior;
- bounded diagnostics.
The code should not require every Ticket body to fit a rigid universal schema. Ticket bodies remain Markdown/freeform because design, cleanup, bugs, investigations, and orchestration epics need different prose.
## Current implementation sequence
1. `ticket-local-files-backend`
2. `ticket-built-in-feature-tools`
3. `ticket-intake-workflow`
4. `ticket-orchestrator-routing`
@@ -0,0 +1,220 @@
# WorkItem definition and API shape
> Superseded on 2026-06-05: the durable orchestration record concept is now named `Ticket`, not `WorkItem`. See `ticket-definition-and-api-shape-20260605.md` and the ticket thread decision for current terminology. This file is retained as historical design context.
## Definition
In Insomnia, a WorkItem is not primarily an issue tracker item. A WorkItem is an agreed execution contract that fixes user intent into a bounded unit that Pods can schedule, delegate, implement, review, and close safely.
Short definition:
> A WorkItem is a durable work contract that preserves user/system-agreed intent and gives Pod groups enough boundary, readiness, and evidence to execute, verify, and complete the work without degrading the original intent.
A ticket file, GitHub Issue, Linear issue, Jira issue, or another tracker record can be a persistence representation of a WorkItem, but none of those representations define the concept itself.
## Roles served by a WorkItem
A WorkItem is simultaneously:
- Intent anchor: preserves what the user and Intake agreed to.
- Delegation packet: lets Orchestrator/Coder understand what should be done and where to stop.
- Review contract: gives Reviewer an explicit basis for approval or request-changes.
- Scheduling unit: lets Orchestrator prioritize, interrupt, parallelize, and assign work.
- Boundary: records scope, non-goals, authority limits, privacy constraints, and escalation conditions.
- Lifecycle record: records plans, decisions, implementation reports, reviews, commits, validation, and resolution.
## Relationship to tickets and issue trackers
- WorkItem is the Insomnia orchestration concept.
- Local markdown ticket is one backend representation.
- GitHub/Linear/Jira issue is another possible backend representation.
- The backend should be abstracted below the WorkItem API.
The WorkItem abstraction should not try to become a complete issue tracker abstraction. It should cover only the subset needed for Insomnia orchestration: create/list/show, structured lifecycle events, status/readiness, review, close, consistency checks, and references/evidence.
## Typing strategy
Use a thin typed envelope with rich Markdown/freeform bodies and events.
The API should type fields that the system reads mechanically, while leaving the content that carries human intent as Markdown/freeform text. This keeps compatibility with external issue trackers and avoids turning Intake into a rigid form-filling flow.
### Typed fields
These should be typed because Orchestrator, TUI, policy, or tools branch on them:
- Identity:
- backend id
- external/work item id
- Classification:
- kind
- priority
- labels as free strings
- State:
- canonical status
- readiness
- action-required state
- needs-preflight flag
- risk flags
- Lifecycle operation/event kind:
- comment
- plan
- decision
- implementation report
- review approved
- review request-changes
- status changed
- closed
- References:
- related WorkItems
- files
- branches
- commits
- Pods
- URLs/artifacts
- Backend capability metadata:
- create/comment/review/close support
- artifact support
- offline support
- transactional/local-git support
Enums should not be closed too tightly. Use escape hatches such as `Other(String)` or canonical+raw mappings for tracker compatibility.
Examples:
```rust
enum WorkItemKind {
Bug,
Task,
Feature,
Design,
Chore,
Other(String),
}
struct MappedStatus {
canonical: WorkItemStatus,
raw: Option<String>,
}
```
### Freeform / Markdown fields
These should remain Markdown/freeform because AI agents and humans can read them well and external trackers can round-trip them:
- issue / problem statement
- user intent
- background / rationale
- requirements
- acceptance criteria
- non-goals
- invariants
- escalation conditions
- investigation notes
- implementation reports
- review comments
- resolution details
The event kind should be typed, but event body should remain Markdown.
```rust
struct WorkItemEvent {
kind: WorkItemEventKind,
body: MarkdownText,
refs: Vec<WorkItemRef>,
}
```
## Suggested initial model
```rust
struct WorkItem {
id: WorkItemId,
title: String,
classification: WorkItemClassification,
state: WorkItemState,
body: WorkItemDocument,
events: Vec<WorkItemEvent>,
refs: Vec<WorkItemRef>,
backend: BackendMetadata,
extensions: serde_json::Map<String, serde_json::Value>,
}
```
```rust
struct WorkItemState {
status: MappedStatus,
readiness: Readiness,
action_required: Option<ActionRequired>,
needs_preflight: bool,
risk_flags: Vec<RiskFlag>,
}
```
```rust
struct WorkItemDocument {
issue: MarkdownText,
requirements: MarkdownText,
acceptance_criteria: MarkdownText,
non_goals: Option<MarkdownText>,
notes: Option<MarkdownText>,
}
```
## API principle
Operations should be typed; payload bodies should be flexible.
Examples:
- `CreateWorkItem(NewWorkItem)` is typed.
- `AddWorkItemEvent { kind, body }` is typed by operation/event kind, freeform in body.
- `UpdateWorkItemState { readiness, action_required, risk_flags }` is typed.
- `CloseWorkItem { resolution: MarkdownText }` has typed operation semantics and freeform resolution text.
This gives enough structure for audit, scheduling, TUI display, and automation, without forcing issue-tracker-specific fields into the core model.
## Lint over hard schema
Prefer a WorkItem linter/policy layer over strict structural enforcement for body content.
Examples:
- title must be present.
- issue/requirements should not be empty.
- P0/P1 items without acceptance criteria should warn.
- risk flags with `needs_preflight = false` should warn.
- secret-like literals should warn or fail depending on policy.
- closing without review/resolution can warn or fail depending on project policy.
This makes the system agent-friendly and backend-compatible while still catching low-quality WorkItems.
## Backend abstraction
Backends should implement WorkItem storage/sync, not redefine WorkItem semantics.
```text
Intake / Orchestrator / TUI / Workflows
WorkItem API
WorkItemBackend
├─ LocalFilesBackend
├─ GitHubIssuesBackend
├─ LinearBackend
├─ JiraBackend
└─ MCPWorkItemBackend
```
Each backend should expose capabilities. The tool/TUI surface should show only operations supported by the configured backend.
## Scope and authority
WorkItem tool authority is separate from normal code/worktree filesystem scope.
Filesystem scope protects exclusive editing of implementation areas. WorkItem management is shared project coordination state and should be mediated by typed WorkItem operations, backend locks/conflict handling, and audit records rather than ordinary delegated write scope.
This does not imply unlimited file access. The WorkItem tool should be limited to configured WorkItem backends and operations.
## Design consequence
The first implementation can be LocalFilesBackend over current `work-items/`, preserving markdown/frontmatter/thread/artifacts and `tickets.sh` compatibility. The API should already be backend-shaped so GitHub Issues or other trackers can be added later without changing Intake/Orchestrator semantics.
+79
View File
@@ -0,0 +1,79 @@
---
title: "Built-in Ticket intake and orchestration routing"
state: "closed"
created_at: "2026-06-01T03:12:52Z"
updated_at: "2026-06-05T06:42:40Z"
---
## Background
Yoi needs a durable project-level coordination record that Intake, Orchestrator, coder Pods, reviewer Pods, and humans can share. The accepted concept name is **Ticket**.
A Ticket is not the same thing as the session-local Task tool. A Task tracks short-lived user-visible progress inside a Pod/session. A Ticket is a durable orchestration contract with requirements, decisions, plans, implementation reports, reviews, artifacts, and resolution history.
The current repository already stores this information under `work-items/` and manages it through `tickets.sh`. For now, that storage format remains the local backend. The new code-facing concept should be `Ticket`, not `WorkItem`; `work-items/` is a current local storage path, not the product concept name.
The original version of this ticket mixed several layers: local ticket backend, built-in Pod tools, Intake behavior, Orchestrator routing, action-required state, and scheduler-like automation. That is too broad for a single implementation ticket, so this ticket now acts as the umbrella tracking ticket for the split.
## Terminology
- `Ticket`: durable orchestration record shared by Intake, Orchestrator, implementation Pods, reviewer Pods, and humans.
- `Task`: session-local progress tracking tool; intentionally separate from Ticket.
- `Assignment`: a concrete delegation from Orchestrator to a coder/reviewer/investigator Pod.
- `IntentPacket`: short implementation/review contract derived from a Ticket and passed to an Assignment.
- `TicketBackend`: backend abstraction for reading and mutating Tickets.
- `LocalTicketBackend`: backend implementation for the current `work-items/` directory format.
## Scope of the umbrella
This umbrella covers the following sequence:
1. `ticket-local-files-backend`
- Add a code-facing Ticket domain model and local backend for current `work-items/` files.
- Keep `tickets.sh` and existing file format compatible.
2. `ticket-built-in-feature-tools`
- Expose Ticket operations as a built-in Pod feature/tool surface.
- Treat Ticket operations as typed backend authority, not arbitrary filesystem writes.
3. `ticket-intake-workflow`
- Define and install an Intake workflow/profile that clarifies user requests and creates Tickets after user agreement.
4. `ticket-orchestrator-routing`
- Let Orchestrator classify Tickets and route them into preflight, implementation, review, spike, blocked/action-required, or close paths.
Later scheduler/lease/automatic maintainer behavior is out of scope for this umbrella until the above pieces are usable.
## Requirements
- Use `Ticket` as the product/code concept name.
- Keep existing `work-items/` storage as the LocalTicketBackend path for now.
- Do not rename the storage directory in this umbrella.
- Keep git history + ticket files authoritative.
- Preserve compatibility with `tickets.sh` until a replacement is explicitly accepted.
- Keep Ticket authority separate from delegated filesystem write scope.
- Avoid exposing arbitrary file writes through Ticket tools.
- Keep Intake focused on clarification and Ticket creation/update; it must not schedule implementation itself.
- Keep Orchestrator responsible for routing/scheduling decisions, not Intake.
- Do not introduce an unattended scheduler in the MVP.
## Acceptance criteria
- This umbrella records the Ticket terminology decision and split plan.
- Child tickets exist for:
- local files backend;
- built-in feature tools;
- intake workflow;
- orchestrator routing.
- Child tickets state their dependencies, scope, non-goals, and acceptance criteria clearly enough for preflight/implementation sequencing.
- Historical `WorkItem` wording in this ticket is either removed or explicitly described as old terminology.
- `tickets.sh doctor` passes after the split.
## Non-goals
- Renaming `work-items/` to `tickets/`.
- Replacing `tickets.sh` immediately.
- Building a scheduler/lease system.
- Building a TUI spawned-Pod panel.
- Changing the session-local Task tool.
- Integrating with GitHub Issues, Linear, MCP, or external trackers in this umbrella.
+43
View File
@@ -0,0 +1,43 @@
Built-in Ticket intake and orchestration routing umbrella is complete.
This umbrella was split into four implementation-sized child tickets, all of which are now closed:
1. `ticket-local-files-backend`
- Added the low-level `ticket` crate, typed Ticket domain/backend, and `LocalTicketBackend` over current `work-items/` files.
2. `ticket-built-in-feature-tools`
- Added built-in Ticket tools through typed backend authority and the Pod feature contribution path.
- Kept Ticket tool behavior in `crates/ticket` and Pod as a thin feature adapter.
3. `ticket-intake-workflow`
- Added `.yoi/workflow/ticket-intake-workflow.md` for clarifying user requests and materializing agreed Tickets after user approval.
4. `ticket-orchestrator-routing`
- Added `.yoi/workflow/ticket-orchestrator-routing.md` for classifying Tickets into requirements sync, preflight, spike, implementation, review, blocked/action-required, close-ready, defer/pending, or no-op paths.
Terminology decision:
- `Ticket` is the durable orchestration record concept.
- `Task` remains session-local progress tracking.
- `Assignment` is concrete Pod delegation.
- `IntentPacket` is the implementation/review contract derived from a Ticket.
- `work-items/` remains the current LocalTicketBackend storage path for now.
Scope preserved:
- The storage directory was not renamed.
- `tickets.sh` remains compatible and in use.
- Ticket authority is separate from delegated filesystem write scope.
- Intake does not schedule implementation.
- Orchestrator routing does not introduce an unattended scheduler/lease/queue system.
- TUI spawned-Pod panel work was deprioritized and is not part of this path.
Validation:
- Child tickets were independently reviewed and validated.
- Final child workflow validation passed `git diff --check` and `./tickets.sh doctor`.
- `./tickets.sh doctor` passes for the umbrella close.
Historical note:
Older thread entries and artifacts may contain superseded `WorkItem` or old system-name wording as historical context. The current terminology and implementation use `Ticket`.
+371
View File
@@ -0,0 +1,371 @@
<!-- event: create author: tickets.sh at: 2026-06-01T03:12:52Z -->
## Created
Created by tickets.sh create.
---
<!-- event: decision author: hare at: 2026-06-01T05:26:27Z -->
## Decision
# WorkItem definition and API shape
## Definition
In Insomnia, a WorkItem is not primarily an issue tracker item. A WorkItem is an agreed execution contract that fixes user intent into a bounded unit that Pods can schedule, delegate, implement, review, and close safely.
Short definition:
> A WorkItem is a durable work contract that preserves user/system-agreed intent and gives Pod groups enough boundary, readiness, and evidence to execute, verify, and complete the work without degrading the original intent.
A ticket file, GitHub Issue, Linear issue, Jira issue, or another tracker record can be a persistence representation of a WorkItem, but none of those representations define the concept itself.
## Roles served by a WorkItem
A WorkItem is simultaneously:
- Intent anchor: preserves what the user and Intake agreed to.
- Delegation packet: lets Orchestrator/Coder understand what should be done and where to stop.
- Review contract: gives Reviewer an explicit basis for approval or request-changes.
- Scheduling unit: lets Orchestrator prioritize, interrupt, parallelize, and assign work.
- Boundary: records scope, non-goals, authority limits, privacy constraints, and escalation conditions.
- Lifecycle record: records plans, decisions, implementation reports, reviews, commits, validation, and resolution.
## Relationship to tickets and issue trackers
- WorkItem is the Insomnia orchestration concept.
- Local markdown ticket is one backend representation.
- GitHub/Linear/Jira issue is another possible backend representation.
- The backend should be abstracted below the WorkItem API.
The WorkItem abstraction should not try to become a complete issue tracker abstraction. It should cover only the subset needed for Insomnia orchestration: create/list/show, structured lifecycle events, status/readiness, review, close, consistency checks, and references/evidence.
## Typing strategy
Use a thin typed envelope with rich Markdown/freeform bodies and events.
The API should type fields that the system reads mechanically, while leaving the content that carries human intent as Markdown/freeform text. This keeps compatibility with external issue trackers and avoids turning Intake into a rigid form-filling flow.
### Typed fields
These should be typed because Orchestrator, TUI, policy, or tools branch on them:
- Identity:
- backend id
- external/work item id
- Classification:
- kind
- priority
- labels as free strings
- State:
- canonical status
- readiness
- action-required state
- needs-preflight flag
- risk flags
- Lifecycle operation/event kind:
- comment
- plan
- decision
- implementation report
- review approved
- review request-changes
- status changed
- closed
- References:
- related WorkItems
- files
- branches
- commits
- Pods
- URLs/artifacts
- Backend capability metadata:
- create/comment/review/close support
- artifact support
- offline support
- transactional/local-git support
Enums should not be closed too tightly. Use escape hatches such as `Other(String)` or canonical+raw mappings for tracker compatibility.
Examples:
```rust
enum WorkItemKind {
Bug,
Task,
Feature,
Design,
Chore,
Other(String),
}
struct MappedStatus {
canonical: WorkItemStatus,
raw: Option<String>,
}
```
### Freeform / Markdown fields
These should remain Markdown/freeform because AI agents and humans can read them well and external trackers can round-trip them:
- issue / problem statement
- user intent
- background / rationale
- requirements
- acceptance criteria
- non-goals
- invariants
- escalation conditions
- investigation notes
- implementation reports
- review comments
- resolution details
The event kind should be typed, but event body should remain Markdown.
```rust
struct WorkItemEvent {
kind: WorkItemEventKind,
body: MarkdownText,
refs: Vec<WorkItemRef>,
}
```
## Suggested initial model
```rust
struct WorkItem {
id: WorkItemId,
title: String,
classification: WorkItemClassification,
state: WorkItemState,
body: WorkItemDocument,
events: Vec<WorkItemEvent>,
refs: Vec<WorkItemRef>,
backend: BackendMetadata,
extensions: serde_json::Map<String, serde_json::Value>,
}
```
```rust
struct WorkItemState {
status: MappedStatus,
readiness: Readiness,
action_required: Option<ActionRequired>,
needs_preflight: bool,
risk_flags: Vec<RiskFlag>,
}
```
```rust
struct WorkItemDocument {
issue: MarkdownText,
requirements: MarkdownText,
acceptance_criteria: MarkdownText,
non_goals: Option<MarkdownText>,
notes: Option<MarkdownText>,
}
```
## API principle
Operations should be typed; payload bodies should be flexible.
Examples:
- `CreateWorkItem(NewWorkItem)` is typed.
- `AddWorkItemEvent { kind, body }` is typed by operation/event kind, freeform in body.
- `UpdateWorkItemState { readiness, action_required, risk_flags }` is typed.
- `CloseWorkItem { resolution: MarkdownText }` has typed operation semantics and freeform resolution text.
This gives enough structure for audit, scheduling, TUI display, and automation, without forcing issue-tracker-specific fields into the core model.
## Lint over hard schema
Prefer a WorkItem linter/policy layer over strict structural enforcement for body content.
Examples:
- title must be present.
- issue/requirements should not be empty.
- P0/P1 items without acceptance criteria should warn.
- risk flags with `needs_preflight = false` should warn.
- secret-like literals should warn or fail depending on policy.
- closing without review/resolution can warn or fail depending on project policy.
This makes the system agent-friendly and backend-compatible while still catching low-quality WorkItems.
## Backend abstraction
Backends should implement WorkItem storage/sync, not redefine WorkItem semantics.
```text
Intake / Orchestrator / TUI / Workflows
WorkItem API
WorkItemBackend
├─ LocalFilesBackend
├─ GitHubIssuesBackend
├─ LinearBackend
├─ JiraBackend
└─ MCPWorkItemBackend
```
Each backend should expose capabilities. The tool/TUI surface should show only operations supported by the configured backend.
## Scope and authority
WorkItem tool authority is separate from normal code/worktree filesystem scope.
Filesystem scope protects exclusive editing of implementation areas. WorkItem management is shared project coordination state and should be mediated by typed WorkItem operations, backend locks/conflict handling, and audit records rather than ordinary delegated write scope.
This does not imply unlimited file access. The WorkItem tool should be limited to configured WorkItem backends and operations.
## Design consequence
The first implementation can be LocalFilesBackend over current `work-items/`, preserving markdown/frontmatter/thread/artifacts and `tickets.sh` compatibility. The API should already be backend-shaped so GitHub Issues or other trackers can be added later without changing Intake/Orchestrator semantics.
---
<!-- event: decision author: hare at: 2026-06-03T12:25:05Z -->
## Decision
# Decision: split feature registry and Hook hardening from Plugin architecture
The Plugin architecture ticket remains the broad architecture surface for Tools, Hooks, runtime kinds, capability model, trust model, discovery/enablement, and MCP/WASM/declarative runtime mapping.
Two implementation-oriented prerequisite tickets are split out:
- `plugin-feature-contribution-registry`: define and implement the Pod-layer feature contribution registry so built-in and future external capabilities register through existing Tool / Hook / Notify paths instead of ad hoc Pod code paths.
- `hook-public-surface-hardening`: audit and harden `pod::hook` before exposing it as a feature/plugin contribution boundary, especially removing public access to raw internal action types that can inject model-visible `Item` values.
This preserves the desired detachable shape: feature state remains in the feature/extension module, while Pod interaction happens through existing durable host surfaces. WorkItem management should be implemented as a built-in feature contribution once the registry boundary is in place, rather than as a special Pod context-injection path.
---
<!-- event: decision author: hare at: 2026-06-05T04:03:37Z -->
## Decision
Decision: use `Ticket` as the durable orchestration record concept.
Rationale:
- `WorkItem` is not a preferred product/code name.
- `Work*` naming feels too enterprise/work-order-like for this system.
- `Issue` overemphasizes problems/bugs and does not fit design, cleanup, investigation, and orchestration records as well.
- `Task` is already used for session-local progress tracking and implies a smaller unit.
- `Ticket` is broad enough for requests, bugs, design work, implementation tasks, reviews, spikes, and orchestration epics while remaining natural in the current repository workflow.
Terminology:
- `Ticket` is the durable orchestration record.
- `Task` remains session-local progress tracking.
- `Assignment` is a concrete delegation from Orchestrator to a coder/reviewer/investigator Pod.
- `IntentPacket` is a short implementation/review contract derived from a Ticket.
- `LocalTicketBackend` is the current `work-items/` markdown/thread/artifact storage backend.
Scope decision:
- Keep `work-items/` as the current storage path for now.
- Do not rename `work-items/` in this phase.
- Treat the old WorkItem wording as historical terminology being replaced by Ticket.
---
<!-- event: plan author: hare at: 2026-06-05T04:03:37Z -->
## Plan
Plan: split the original broad built-in intake/routing ticket into implementation-sized Ticket tickets.
The parent ticket is now an umbrella for the Ticket-driven intake/orchestration path. The implementation sequence is:
1. `ticket-local-files-backend`
- Add the code-facing Ticket domain/backend layer and LocalTicketBackend over current `work-items/` files.
2. `ticket-built-in-feature-tools`
- Expose typed Ticket operations as a built-in Pod feature/tool surface with Ticket backend authority, not arbitrary filesystem write scope.
3. `ticket-intake-workflow`
- Add the Intake workflow/profile that clarifies user intent and creates/updates Tickets after user agreement.
4. `ticket-orchestrator-routing`
- Add explicit Orchestrator routing classification and intent-packet production for Tickets.
`tui-spawned-pod-panel` is not part of this path; it may be useful UI work later, but it is not what is currently needed for the multi-agent system.
---
<!-- event: comment author: hare at: 2026-06-05T04:04:42Z -->
## Comment
Added current terminology/design artifact:
- `artifacts/ticket-definition-and-api-shape-20260605.md`
The earlier `workitem-definition-and-api-shape-20260601.md` is now explicitly marked superseded and retained only as historical context.
---
<!-- event: close author: hare at: 2026-06-05T06:42:40Z status: closed -->
## Closed
Built-in Ticket intake and orchestration routing umbrella is complete.
This umbrella was split into four implementation-sized child tickets, all of which are now closed:
1. `ticket-local-files-backend`
- Added the low-level `ticket` crate, typed Ticket domain/backend, and `LocalTicketBackend` over current `work-items/` files.
2. `ticket-built-in-feature-tools`
- Added built-in Ticket tools through typed backend authority and the Pod feature contribution path.
- Kept Ticket tool behavior in `crates/ticket` and Pod as a thin feature adapter.
3. `ticket-intake-workflow`
- Added `.yoi/workflow/ticket-intake-workflow.md` for clarifying user requests and materializing agreed Tickets after user approval.
4. `ticket-orchestrator-routing`
- Added `.yoi/workflow/ticket-orchestrator-routing.md` for classifying Tickets into requirements sync, preflight, spike, implementation, review, blocked/action-required, close-ready, defer/pending, or no-op paths.
Terminology decision:
- `Ticket` is the durable orchestration record concept.
- `Task` remains session-local progress tracking.
- `Assignment` is concrete Pod delegation.
- `IntentPacket` is the implementation/review contract derived from a Ticket.
- `work-items/` remains the current LocalTicketBackend storage path for now.
Scope preserved:
- The storage directory was not renamed.
- `tickets.sh` remains compatible and in use.
- Ticket authority is separate from delegated filesystem write scope.
- Intake does not schedule implementation.
- Orchestrator routing does not introduce an unattended scheduler/lease/queue system.
- TUI spawned-Pod panel work was deprioritized and is not part of this path.
Validation:
- Child tickets were independently reviewed and validated.
- Final child workflow validation passed `git diff --check` and `./tickets.sh doctor`.
- `./tickets.sh doctor` passes for the umbrella close.
Historical note:
Older thread entries and artifacts may contain superseded `WorkItem` or old system-name wording as historical context. The current terminology and implementation use `Ticket`.
---