Resolutions:
- `docs/subsystems/schedule.*` and `packages/client/ui-schedule/README.*` keep
this branch's shipped-composition text with master's newer wording (Rules and
Records tabs, the icon-button linked-session layout).
- `docs/event-producer-consumer.*` regenerated by `gen-doc-graphs`.
Only packages/typert/loader/tests/loader.spec.ts conflicted. Master's side
was kept (master's non-awaited ctx.loader.remove calls, restored by the revert
of the transactional Cordis reload changes) and this branch's two vi.waitFor
conversions were re-applied on top, so the merged file differs from master
only by those two polling assertions.
`@deepseek-ai/dsh-schedule` and `@deepseek-ai/dsh-tool-schedule` now depend on
`@deepseek-ai/dsh-subagent`, and the schedule package no longer imports the
Session controller's ownership predicate, so the committed module graph moves.
Review follow-ups on the delegated-child rule:
- Every one of the four tools refuses a delegated caller before dispatch,
reading `delegationDepthOf(exec.agent)` and returning the stable
`subagent_session` refusal, so `schedule_list`, `schedule_delete`, and a
content-only `schedule_update` are covered too. The preset `toolFilter.deny`
stays as the layer that keeps the tools out of a child's prompt.
- The service keys the arming refusal on that same delegation accounting
alone; `hasApiSessionSubagentOwner` returns to package-private and
`@deepseek-ai/dsh-schedule` no longer imports it.
- The preset child row is `time-context` again: the `preset-` prefix separated
it from a Host row that no longer exists, and `verify-cordis-config` passes
with the sibling-style id.
- Docs, Agent Notes, and the generated catalogs follow.
Move the auto-growing textarea into ui-primitives as InlineEditor and use it
for both the queued-message and goal editors. It also refits when its width
changes and treats keyCode 229 as IME composition.
A delegated child could arm reminders through the tools its preset mount
passes down, even though delivery can never reach a child's Session. The
refusal now reads the delegation-depth accounting the delegation cap itself
enforces, and the shipped presets deny the four tools to children outright:
- `reminderTargetRefusal` refuses when `delegationDepthOf(agent)` is above
zero, or when the Session is subagent-owned without a depth record.
- `standard`, `cordis`, and `ptc` set `toolFilter.deny` on both delegation
rows, so the four tools leave a child's prompt and reject execution.
`create` still rejects and `update` still returns the non-mutating refusal.
Tighten goal-round-driver docs and regression assertions for the withdrawn
queued round: continuation disarms when the cancelled turn belonged to other
work, and the removal is a durable canceled next-turn splice.
Render one Button for both layouts so crossing the fit threshold keeps focus,
anchor the tooltip on the wrapper so a disabled compact entry still names
itself, observe each tab, and rename the tab in the user and subsystem docs.
Rebind the scrollbar thumb to the l2 pair on the elevated goal strip, treat
keyCode 229 as IME composition, and re-measure the editor when the inline
error changes its width.
The classification was recorded before the subtree scan, so a run that found and
removed package ACEs under the requested directory still reported NOT_THIS_CLASS
or PRECONDITION with an empty packageObjects, contradicting README and SKILL. The
scan now runs first, so the verdict and packageObjects describe what the run
actually repairs.
A report-file write failure now prints REPORT_IO_FAILED with the path and the
error on stderr instead of silently leaving an incomplete report behind.
Shrink the linked Session entry to a chat icon button with a Linked session
tooltip when the detail strip cannot fit it, hide the tab list scrollbar,
and rename the English Delivery records tab to Records.
A goal round queued behind human work stayed in the inbox after Stop. The
next human prompt claimed that stale round first, pre-step rejected it, and
the driver exited with the human prompt still parked until another send.
The goal edit field was a single-line input: Enter always saved, a newline
could not be entered, and a long objective scrolled sideways on one line.
Use an auto-growing textarea capped at six lines, matching the queued-message
editor: Enter saves, Shift+Enter breaks the line, IME confirmation does not
save, Escape cancels.