10 KiB
Created
Created by tickets.sh create.
Decision
Investigation: Task state and Hook side-effect boundary
Findings
- Hook action types are already separated per hook point after Hook hardening. The next design should preserve that: flow-control actions stay event-specific rather than becoming one global
HookDecision. - Hook inputs are still summary structs, not contexts with host-created handles. That is the missing abstraction for feature-owned behavior that needs durable host side effects.
TaskStoreis still owned byPod, andTaskReminderState/reminder emission is still owned byPodInterceptor.- The Task built-in feature module currently contributes only the four Task tools and receives
TaskStorefrom Pod. This is an incomplete internal-module boundary: Task-specific state still remains on the Pod side. SystemItem::TaskReminderis currently appended throughPodInterceptor::pending_history_appends(), which is the correct durable history direction but the wrong ownership location for Task-specific logic.
Decision
Split follow-up into two steps:
- Add Hook context host handles, especially a durable
SystemItemappend handle. Hook returns remain per-hook-point flow-control actions. No rawIteminjection and no generic effect/event channel. - Move TaskStore and Task reminder logic into the Task feature module, implemented as Task-owned tools plus hooks that use the host-provided SystemItem append handle.
This keeps Pod responsible for generic host surfaces and history authority, while Task owns Task-specific state and policy.
Plan
Delegation intent: Hook context SystemItem append sink
Intent
Implement the first step in the Task state/reminder cleanup sequence: add event-specific Hook context support with a host-mediated durable SystemItem append handle, while keeping Hook return actions as per-hook-point flow-control actions.
This is the prerequisite for moving TaskStore/reminder logic into the Task feature. Do not move TaskStore or Task reminders in this ticket.
Worktree / branch
- worktree:
/home/hare/Projects/yoi/.worktree/hook-context-system-item-sink - branch:
work/hook-context-system-item-sink
Requirements
- Evolve the public Pod Hook API so Hook handlers receive event-specific context values rather than only bare summary inputs where necessary.
- Preserve the existing per-hook-point action/output types.
- Do not collapse actions into one global
HookDecision.
- Add a host-created typed handle for durable model-visible
SystemItemappend.- Suggested naming:
SystemItemAppendHandle,SystemItemSink, or equivalent. - Constructors/fields must stay host-private; feature/hook code can only use handles the host provides.
- The handle must not expose raw
llm_worker::Item, raw history writers, raw event senders, rawPod, rawWorker, orNotifyBuffer.
- Suggested naming:
- The append path must use existing durable history semantics:
- host-controlled pending append / commit path;
LogEntry::SystemItem;Event::SystemItem;- model context visibility only after durable commit.
- The initial approved system-item requests should be narrow.
- Support what is needed for a future
TaskReminderhook, and notification-like system items only if this falls out naturally from existingSystemItemmachinery. - Do not introduce arbitrary
llm_worker::Itemappend or generic plugin event channels.
- Support what is needed for a future
- Keep built-in internal modules distinct from external-plugin authority approval.
- It is okay to add scaffolding so internal hooks can receive the handle by host policy.
- Do not implement external-plugin approval or WASM imports in this ticket.
- Preserve current observable behavior.
- Current Task reminders should continue to be emitted by existing
PodInterceptorlogic until the follow-up ticket moves them. - Existing Hook tests and permission hook behavior must continue to pass.
- Current Task reminders should continue to be emitted by existing
Non-goals
- Moving
TaskStoreownership into the Task feature. - Moving
TaskReminderStateorPodInterceptorreminder logic. - TUI UI/dialog work.
- Generic event channel / arbitrary UI payloads.
- External plugin loading or package approval.
- Changing ToolRegistry / PreToolCall permission behavior.
- Reintroducing raw
Iteminjection,ContinueWith(Vec<Item>), no-result tool skip, or arbitraryToolResultconstruction.
Suggested files
crates/pod/src/hook.rscrates/pod/src/ipc/interceptor.rscrates/pod/src/pod.rscrates/pod/src/controller.rscrates/session-store/src/system_item.rsor whereverSystemItemrequest/serialization is defined- existing Hook tests in
crates/pod/src/**
Validation
Run at least:
- focused Hook context / SystemItem sink tests added by this ticket
cargo test -p pod hook --libcargo test -p pod --libcargo test -p llm-worker --libcargo check --workspace --all-targetscargo fmt --check./tickets.sh doctorgit diff --check
Run nix build .#yoi if feasible.
Escalate if
- Implementing the handle requires changing session/history commit semantics.
- The only easy path is to expose raw
Item, raw history writers, raw event senders, orPod/Workerinternals. - Hook action types would need to be merged into one generic return type.
- Current Task reminder behavior would change before the Task ownership follow-up.
Completion report
Report:
- worktree path / branch
- commit hash
- changed files
- Hook context/action API changes
- SystemItem append handle design and path to durable commit
- tests added/updated
- validation results
- unresolved risks/follow-ups
- whether ready for external review
Plan
Delegation intent: Task feature owns TaskStore and reminders
Intent
Implement the second step in the Task feature cleanup sequence: move Task-specific state and reminder behavior out of Pod / PodInterceptor and into the built-in Task feature module.
The prerequisite hook-context-system-item-sink is closed. Use its PreRequestContext / SystemItemAppendHandle path for durable SystemItem::TaskReminder append. Pod should provide generic host surfaces; Task feature should own Task state and policy.
Worktree / branch
- worktree:
/home/hare/Projects/yoi/.worktree/task-feature-own-store-reminder-hooks - branch:
work/task-feature-own-store-reminder-hooks
Requirements
- Move TaskStore construction/ownership from
Podinto the built-in Task feature module.- The Task feature should own the session-lifetime
tools::TaskStoreshared by Task tools and reminder hooks. - Pod should not keep a Task-specific store field merely because tools/reminders need it.
- The Task feature should own the session-lifetime
- Move TaskReminderState and reminder decision logic out of
PodInterceptorand into Task feature-owned hooks.- Use a tool hook to record Task tool usage.
- Use a
PreLlmRequesthook to evaluate inactivity/cooldown and appendSystemItem::TaskReminderthroughSystemItemAppendHandle. - Preserve the current threshold/cooldown/body/source semantics.
- Remove Task-specific checks from
PodInterceptor, including task-tool-name special-casing for reminder state, once feature-owned hooks replace them. - Preserve current observable behavior:
- TaskCreate / TaskUpdate / TaskGet / TaskList names, schemas, descriptions, outputs;
- TaskStore snapshot/restore behavior;
- task reminder emission timing/body/cooldown;
- model-visible history path via
LogEntry::SystemItem/Event::SystemItem; - normal ToolRegistry / PreToolCall permission path.
- Audit all current
Pod::task_store/task_storeuses.- If Pod/session restore/compaction/TUI compatibility needs read access, route it through a Task feature-owned status/snapshot surface or a documented temporary façade that does not make Pod the owner.
- Do not silently drop restore/snapshot/compaction behavior.
- Keep external-plugin authority model out of this ticket except using the trusted built-in hook handle path already implemented.
- Keep TUI UI changes out of scope.
Important constraints
- Do not expose raw
llm_worker::Item, raw history writers, raw event senders, rawPod, rawWorker, or rawNotifyBufferthrough the Task feature. - Do not reintroduce raw
ContinueWith(Vec<Item>), no-result tool skip, arbitraryToolResultconstruction, generic event channels, or UI/dialog payloads. - Do not change external plugin loading, package approval, WASM, MCP, WorkItem, Memory, or Pod-management modules.
- Do not remove the existing Task tools or change their model-visible metadata.
Suggested files
crates/pod/src/feature/builtin/task.rscrates/pod/src/feature.rscrates/pod/src/hook.rscrates/pod/src/ipc/interceptor.rscrates/pod/src/pod.rscrates/pod/src/controller.rscrates/tools/src/task.rs- any tests around TaskStore snapshot/restore and Task reminders
Validation
Run at least:
- focused Task feature/reminder tests added or moved by this ticket
cargo test -p pod hook --libcargo test -p pod --libcargo test -p llm-worker --libcargo check --workspace --all-targetscargo fmt --check./tickets.sh doctorgit diff --check
Run nix build .#yoi if feasible.
Escalate if
- Preserving TaskStore snapshot/restore requires TUI/protocol changes.
- Removing Pod ownership would require a broad feature-service/status API beyond this ticket.
- Current reminder semantics cannot be preserved through Hook order or SystemItem append timing.
- You find any hidden dependency that requires TaskStore to remain Pod-owned.
Completion report
Report:
- worktree path / branch
- commit hash
- changed files
- where TaskStore is now owned
- how Task reminder state/logic moved into Task feature hooks
- how snapshot/restore/compaction behavior is preserved
- evidence Pod/PodInterceptor no longer own or special-case Task state
- tests/validation results
- unresolved risks/follow-ups
- whether ready for external review