You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Status: pending
Tags: enhancement, assistant, work-engine, backend, infra, testing, data, P1
Parent: #122
Depends on: #121, #124, #125
Blocks: Typefully saved-draft and rollout children of #122
Architecture: _docs/CONVERSATIONAL_AGENT_PLUGIN_ARCHITECTURE.md at 4e5402c
Product decisions
This is the first complete production mutation through the conversational framework. It creates exactly one ordinary todo task in the authenticated actor's own scope after an exact preview and core approval.
The resulting task always has status=todo, assigneeId=<authenticated DataOps user>, createdBy=<same user>, and source=conversational-agent. The plugin cannot choose another assignee, status, owner, bundle, recurring rule, time, reminder, waiting state, tags, links, documents, proof fields, or arbitrary task properties.
DataOps operational dates use Europe/Berlin for this MVP. The runtime gives the model the current Berlin calendar date. Relative dates may be resolved to an exact date only when unambiguous; the exact date and timezone are shown in the preview. If the date is missing or ambiguous, ask. If a request contains a specific time, explain that this MVP stores a date only and ask the user to confirm the date-only todo instead of silently dropping the time.
There is no /todo mutation command. /todo with or without arguments returns a short static instruction to describe the task in an ordinary private message and invokes neither the model nor task writer.
Do not route execution through the generic POST /api/tasks handler or the current unrestricted createTask(client, Record<string, unknown>) function. Add a narrow actor-owned todo writer used only by the durable execution worker. Existing task API behavior remains compatible.
An internal DynamoDB task write is recoverable by deterministic identity and conditional creation. If the task commit succeeds but the worker loses its response, do not delete or compensate the task; recovery returns the same task and completes the original attempt. This is safer and simpler than an automatic rollback that could remove a visible task.
Operator journey
A linked, active user sends an ordinary message in a Telegram private chat, for example: “Remind me to follow up with Jane next Tuesday.”
The runtime loads the registered todo plugin in turn one and invokes its strict propose_create action in the separate turn two.
The plugin asks only for missing or ambiguous description/date information. It never creates a task during clarification.
The bot presents one normalized todo:
Todo
Task: Follow up with Jane
Date: 2026-08-04 (Europe/Berlin, date only)
Assignee: You
Status: Todo
Core controls are Approve todo, Request changes, Cancel proposal, and Discard draft.
Request changes keeps the draft, gathers the requested correction, supersedes the old proposal/presentation, and shows a complete new preview. An old approval button cannot approve the revision.
The Add transactional approval and durable execution recovery #124 worker invokes only the todo writer. On success, the bot reports one created todo with its task ID, normalized description, and exact date. Duplicate taps/deliveries return the stored result.
A proved pre-write failure says no todo was created and allows a fresh proposal. An uncertain internal write is reconciled by deterministic task identity/strong lookup and never creates a second task.
Ordinary conversation remains the interface. A detached “yes”, a new message after proposal expiry, a group message, or an unconfirmed voice/photo derivation is not approval.
Todo plugin
Register one trusted static plugin in #125's registry:
The production action schema uses additionalProperties: false and accepts exactly description and date. Timezone, actor/assignee, status, source, proposal identity, and execution identity come from trusted core state rather than model input.
The validator must:
normalize description to Unicode NFKC, trim it, collapse ordinary whitespace, and reject control/zero-width characters, empty content, or more than 500 characters;
accept only a real Gregorian YYYY-MM-DD date, not a timestamp or free-form date;
reject any extra field, multiple todo, list/array, alternate assignee/owner, status, time/reminder, recurrence, or embedded mutation instruction;
return typed missing/ambiguous-field results rather than guessing;
treat model/plugin text as untrusted and never interpret description text as instructions;
authenticated actor/owner/assignee DataOps user ID;
conversation/draft references, permission todo:create:self, and expiry;
no existing target/base revision, because this is create-only.
The deterministic renderer displays every operator-relevant field listed in the journey. The executor receives only the stored approved spec; it cannot add fields or reinterpret the description.
Clarification, revision, and cancellation
Missing description: ask what task should be created.
Missing date: ask for the date.
Relative date that has one answer from the supplied Berlin current date: convert it and show the exact result in preview.
Ambiguous date, locale, or reference such as “then”, “next time”, or an unresolved “that”: ask one concise question; do not search broad history or invent context.
Specific time/reminder request: state that this version stores a date only and ask whether to continue for the exact displayed date.
Multiple requested tasks: explain that one proposal creates one todo and ask which single todo to prepare first. Do not silently choose or create a batch.
Request changes: update the PluginDraft at its expected revision, create a new immutable proposal version, and revoke/supersede every old presentation.
Cancel proposal: revoke approval controls but keep the draft/conversation according to core semantics.
Discard draft: abandon it according to core semantics.
Expired proposal: explain that approval expired and regenerate a current preview before presenting a fresh control.
No clarification, model retry, revision, cancel, discard, expiry, or session action calls the writer.
Capability-limited actor-owned task writer
Add a typed ActorTodoWriter separate from generic task CRUD. It accepts only a trusted execution envelope from #124 plus the stored todo spec:
attempt ID and current lease generation
proposal ID/version and canonical payload hash
actor/owner DataOps user ID
description
date
It derives a stable task ID and idempotency identity from the execution attempt/proposal, not from random UUIDs or Telegram deliveries. It writes exactly:
id
description
date
status=todo
source=conversational-agent
assigneeId=actor user ID
createdBy=actor user ID
createdAt / updatedAt
assistantExecutionRef:
executionAttemptId
proposalId / proposalVersion
canonicalPayloadHash
The provenance is safe metadata: no conversation text, Telegram IDs, action tokens, model output, prompt, or secret.
Use one DynamoDB transaction for the internal effect:
put the deterministic task only if its key does not exist.
On a conditional collision, strongly read the deterministic task:
if actor, proposal, attempt, payload hash, description, and date all match, return the same successful safe receipt;
if any value differs, return a redacted failed_safe idempotency conflict and never overwrite the task.
The writer exposes no update/delete/list/arbitrary-put capability. The execution worker role receives only the additional task-table GetItem, conditional PutItem, and transaction permissions required by this contract. It receives no task update/delete/scan/query permission.
The safe result receipt contains task ID, actor ID, proposal/attempt references, canonical payload hash, and timestamps. It contains no callback token, prompt/model body, Telegram identifier, or private conversation body.
Extend the Task contract and portable task export/validation/restore only as needed for createdBy and the bounded assistantExecutionRef. Existing task rows without these optional fields remain valid. Export validation rejects malformed or secret-bearing provenance.
Authorization and conflict behavior
The plugin is visible/invocable only for an active linked admin or operator in a private Telegram channel with todo:create:self.
Authorization is rechecked by #125 before invocation, by #124 at approval, and by #124 immediately before the todo writer. The writer additionally binds the attempt/proposal actor to the task owner/assignee in its transaction.
These cases execute nothing:
unlinked, revoked, disabled, wrong-role, wrong-channel, or group actor;
detached text such as “yes” without the exact core approval action;
missing/ambiguous/invalid description or date;
more than one todo or any unsupported field;
stale/expired worker lease or mismatched execution envelope.
Create-only todo has no mutable canonical target/base revision. Its conflicts are proposal revision/build/policy/hash drift and deterministic task-ID collisions. A conflict never overwrites an existing task; the user must generate and approve a current proposal.
Failure, recovery, and rollback semantics
Before approval: there is no task to roll back.
Approval transaction failure: no attempt and no task.
Failure before the task transaction: record/prove failed_safe; no task.
Failure of the task transaction: no partial task because DynamoDB transactions are atomic.
Stale worker result: cannot overwrite the attempt or task because both the task transaction and attempt finalization check the lease generation.
Cancel/request changes after approval cannot promise rollback once execution is pending/executing. The bot explains that submitted execution cannot be canceled. This issue adds no task deletion/undo.
No automatic rollback deletes a created task. If a later operator wants deletion or update, they use existing authorized task workflows outside this plugin; adding conversational update/delete is a separate issue.
Acceptance criteria
The production static registry contains one todo plugin with only propose_create, todo:create:self, private Telegram role/channel restrictions, and a strict two-field schema.
The writer accepts only the capability-limited schema, rechecks the current attempt lease/proposal/actor transactionally, assigns the task to the actor, and cannot update/delete/query arbitrary tasks.
One approved proposal creates at most one task with exact approved description/date and fixed status/source/ownership/provenance fields.
Duplicate callback, update, Stream delivery, worker lease, timeout, and recovery return the same task/result and cannot create another task.
Wrong actor/channel, revoked permission, stale revision/build/hash/lease, unsupported fields, and deterministic ID collision create no task and overwrite nothing.
Failure before/inside the write leaves no task; a post-commit lost response preserves and reconciles the one task rather than deleting/recreating it.
/todo never invokes the model, plugin, approval flow, or task writer and returns only static conversational guidance.
The current Telegram direct-task compatibility route no longer creates a task from an ordinary message before approval.
Existing generic task API, task records without assistant provenance, exports/restores, and unrelated assistant/Telegram behavior remain compatible.
Audit/status/result data is bounded and redacted; it contains no token, prompt/completion, Telegram identifier, secret, or raw conversation body.
SAM grants the execution worker only the minimal additional task-table permissions and does not grant task mutation to the model/runtime or Telegram webhook path.
[HUMAN] In the deployed sandbox, one linked operator sends an ordinary private Telegram todo request, answers one clarification, requests one revision, approves the exact preview, and confirms exactly one matching task exists. Repeated approval produces no second task, while /todo produces no task.
Test scenarios
Ordinary conversation and clarification
Given an active linked private user, fake z.ai responses, and requests with complete, missing, ambiguous, relative-date, exact-time, and multi-todo content
When #121 and #125 process each input
Then complete single input reaches one preview, missing/ambiguous values ask one question, relative dates show an exact Berlin date, time requests require date-only confirmation, multi-todo requests select none, and the task writer call count is zero.
Strict plugin schema
Given descriptions with whitespace/Unicode/control/zero-width/oversize variants, valid/invalid dates, arrays, extra fields, alternate assignees/statuses, and embedded instruction-like text
When propose_create validates them
Then only one normalized description plus real date is accepted, instruction-like description remains inert data, unsupported fields are rejected, and no invalid proposal/writer call exists.
Exact preview and revision
Given proposal v1 and revisions changing description or date
When previews are rendered and old/new controls are used
Then each preview/hash contains all current fields, v1 is superseded/revoked, v1 approval creates nothing, and only exact approval of the current version may queue one attempt.
Approval and actor isolation
Given active, disabled, revoked, unlinked, other-user, group, stale-plugin, expired, canceled, and detached-“yes” cases
When invocation or approval is attempted
Then only the exact active actor/private-channel/current-presentation path queues execution; every other case creates no attempt/task and reveals no other user's state.
Capability and field confinement
Given a malicious model/plugin candidate and direct writer calls containing owner/status/bundle/recurrence/time/link/update/delete/arbitrary fields
When validation and execution run
Then every extra capability is rejected, the writer exposes no generic task client, and a valid result contains only the fixed actor-owned todo fields and safe provenance.
Concurrent approval and execution
Given 25 simultaneous approval callbacks, duplicate Telegram updates/Stream records, and concurrent workers
When the full flow runs against DynamoDB Local
Then one proposal/attempt/task ID wins, one task row exists, all idempotent success paths report that same task, and the task contents equal the approved preview.
Conflict and authorization revocation
Given proposal revision/build/schema/policy/hash changes, deterministic task-ID collision with different data, identity disablement, permission revocation, and a stale worker lease
When approval/recovery runs
Then no mismatched task is created or overwritten, no stale worker dispatch succeeds, and the attempt records a safe conflict/failure requiring a fresh proposal where appropriate.
Crash and rollback boundaries
Given injected failure (a) before approval commit, (b) after approval before lease, (c) before task transaction, (d) during transaction, (e) after task commit before return, and (f) after return before attempt-result write
When #124 recovery runs
Then (a,c,d) leave no task, (b) eventually executes, and (e,f) find the exact existing deterministic task and finalize once without delete/recreate/duplicate.
Command and legacy bypass regression
Given /todo, /todo buy milk tomorrow, and the legacy ordinary direct-task input
When the Telegram route processes them
Then commands return static guidance with zero model/writer calls, ordinary input enters conversation/preview, and no compatibility path creates a task before approval.
Export, restore, and redaction
Given ordinary tasks plus conversational todo tasks and malformed/secret-bearing assistant provenance
When portable export validation, dry-run import, and restore tests run
Then optional safe provenance round-trips, legacy tasks remain valid, unsafe provenance fails without echoing the value, and restored records cannot replay an approval.
Infrastructure permissions
Given the SAM template and deployed-role assertions
When validation runs
Then only the execution worker gains the required task GetItem/conditional PutItem/transaction access, while the model/runtime and Telegram webhook paths cannot write tasks directly through this plugin.
Required verification
Software Engineer and Tester must run:
npm --prefix backend test
npm --prefix backend run typecheck
npm --prefix backend run build
make sam-validate
make sam-build
Also run focused DynamoDB Local tests for plugin validation, actor isolation, 25-way approval concurrency, deterministic task collisions, lease enforcement, all crash boundaries, legacy bypass removal, and portable export/restore provenance. Use injected clocks/current Berlin date, fake z.ai, fake Telegram transport, and no external network or real provider write.
Run the existing Telegram, task API/data-layer, conversational runtime, approval/worker/recovery, portable export, restore, and SAM/IAM test suites in full. Assistant Engineer reviews the plugin/executor boundary before Tester acceptance.
No portal UI changes are in scope, so Playwright/screenshots are not required unless implementation unexpectedly changes a web surface; Tester must explain any omission. The real Telegram/task creation is only the single [HUMAN] sandbox gate above. When all automated work passes first, ship with Refs #126, add human, and leave the issue open until that gate is complete.
Dependencies
Consolidate private Telegram identity, text, voice, and photo input #121 supplies linked private Telegram identity, ordinary text/confirmed media event normalization, conversations, callback/status rendering, and group fail-closed behavior. Preserve this dependency ID even while its grooming is underway.
Implementation must not weaken a dependency contract. If #121's final interface names differ, adapt this slice to its normalized private-message/action contracts without adding a second Telegram path.
Out of scope
/todo mutation shortcut, slash-command parsing into a proposal, or command-based approval.
More than one todo per proposal, batches, partial success, bulk import, or multi-effect plans.
Ship approved conversational todo creation
Status: pending
Tags:
enhancement,assistant,work-engine,backend,infra,testing,data,P1Parent: #122
Depends on: #121, #124, #125
Blocks: Typefully saved-draft and rollout children of #122
Architecture:
_docs/CONVERSATIONAL_AGENT_PLUGIN_ARCHITECTURE.mdat4e5402cProduct decisions
This is the first complete production mutation through the conversational framework. It creates exactly one ordinary
todotask in the authenticated actor's own scope after an exact preview and core approval.Keep the first todo schema deliberately small:
The resulting task always has
status=todo,assigneeId=<authenticated DataOps user>,createdBy=<same user>, andsource=conversational-agent. The plugin cannot choose another assignee, status, owner, bundle, recurring rule, time, reminder, waiting state, tags, links, documents, proof fields, or arbitrary task properties.DataOps operational dates use
Europe/Berlinfor this MVP. The runtime gives the model the current Berlin calendar date. Relative dates may be resolved to an exact date only when unambiguous; the exact date and timezone are shown in the preview. If the date is missing or ambiguous, ask. If a request contains a specific time, explain that this MVP stores a date only and ask the user to confirm the date-only todo instead of silently dropping the time.There is no
/todomutation command./todowith or without arguments returns a short static instruction to describe the task in an ordinary private message and invokes neither the model nor task writer.Do not route execution through the generic
POST /api/taskshandler or the current unrestrictedcreateTask(client, Record<string, unknown>)function. Add a narrow actor-owned todo writer used only by the durable execution worker. Existing task API behavior remains compatible.An internal DynamoDB task write is recoverable by deterministic identity and conditional creation. If the task commit succeeds but the worker loses its response, do not delete or compensate the task; recovery returns the same task and completes the original attempt. This is safer and simpler than an automatic rollback that could remove a visible task.
Operator journey
A linked, active user sends an ordinary message in a Telegram private chat, for example: “Remind me to follow up with Jane next Tuesday.”
The Consolidate private Telegram identity, text, voice, and photo input #121 adapter records the event and passes text—or already confirmed voice/photo-derived text—to the Build the static plugin runtime and z.ai conversational adapter #125 runtime.
The runtime loads the registered
todoplugin in turn one and invokes its strictpropose_createaction in the separate turn two.The plugin asks only for missing or ambiguous description/date information. It never creates a task during clarification.
The bot presents one normalized todo:
Core controls are Approve todo, Request changes, Cancel proposal, and Discard draft.
Request changes keeps the draft, gathers the requested correction, supersedes the old proposal/presentation, and shows a complete new preview. An old approval button cannot approve the revision.
Approve todo uses Add transactional approval and durable execution recovery #124's atomic claim and returns
execution_pending. No task is written in the Telegram webhook/model request.The Add transactional approval and durable execution recovery #124 worker invokes only the todo writer. On success, the bot reports one created todo with its task ID, normalized description, and exact date. Duplicate taps/deliveries return the stored result.
A proved pre-write failure says no todo was created and allows a fresh proposal. An uncertain internal write is reconciled by deterministic task identity/strong lookup and never creates a second task.
Ordinary conversation remains the interface. A detached “yes”, a new message after proposal expiry, a group message, or an unconfirmed voice/photo derivation is not approval.
Todo plugin
Register one trusted static plugin in #125's registry:
The production action schema uses
additionalProperties: falseand accepts exactlydescriptionanddate. Timezone, actor/assignee, status, source, proposal identity, and execution identity come from trusted core state rather than model input.The validator must:
YYYY-MM-DDdate, not a timestamp or free-form date;The immutable
ProposalSpecbinds:plugin=todo, exact build/schema/policy digests, andaction=propose_create;operation=create,effect=task.create, and destinationdataops.tasks;status=todo,source=conversational-agent,timeZone=Europe/Berlin;todo:create:self, and expiry;The deterministic renderer displays every operator-relevant field listed in the journey. The executor receives only the stored approved spec; it cannot add fields or reinterpret the description.
Clarification, revision, and cancellation
PluginDraftat its expected revision, create a new immutable proposal version, and revoke/supersede every old presentation.No clarification, model retry, revision, cancel, discard, expiry, or session action calls the writer.
Capability-limited actor-owned task writer
Add a typed
ActorTodoWriterseparate from generic task CRUD. It accepts only a trusted execution envelope from #124 plus the stored todo spec:It derives a stable task ID and idempotency identity from the execution attempt/proposal, not from random UUIDs or Telegram deliveries. It writes exactly:
The provenance is safe metadata: no conversation text, Telegram IDs, action tokens, model output, prompt, or secret.
Use one DynamoDB transaction for the internal effect:
executing, belongs to this exact proposal/actor, has this payload hash, and is owned by the supplied unexpired lease generation;On a conditional collision, strongly read the deterministic task:
failed_safeidempotency conflict and never overwrite the task.The writer exposes no update/delete/list/arbitrary-put capability. The execution worker role receives only the additional task-table
GetItem, conditionalPutItem, and transaction permissions required by this contract. It receives no task update/delete/scan/query permission.The safe result receipt contains task ID, actor ID, proposal/attempt references, canonical payload hash, and timestamps. It contains no callback token, prompt/model body, Telegram identifier, or private conversation body.
Extend the
Taskcontract and portable task export/validation/restore only as needed forcreatedByand the boundedassistantExecutionRef. Existing task rows without these optional fields remain valid. Export validation rejects malformed or secret-bearing provenance.Authorization and conflict behavior
The plugin is visible/invocable only for an active linked
adminoroperatorin a private Telegram channel withtodo:create:self.Authorization is rechecked by #125 before invocation, by #124 at approval, and by #124 immediately before the todo writer. The writer additionally binds the attempt/proposal actor to the task owner/assignee in its transaction.
These cases execute nothing:
Create-only todo has no mutable canonical target/base revision. Its conflicts are proposal revision/build/policy/hash drift and deterministic task-ID collisions. A conflict never overwrites an existing task; the user must generate and approve a current proposal.
Failure, recovery, and rollback semantics
failed_safe; no task.No automatic rollback deletes a created task. If a later operator wants deletion or update, they use existing authorized task workflows outside this plugin; adding conversational update/delete is a separate issue.
Acceptance criteria
todoplugin with onlypropose_create,todo:create:self, private Telegram role/channel restrictions, and a strict two-field schema.Europe/Berlindate and the preview always displays an exactYYYY-MM-DD, timezone, and “date only” semantics.execution_pending, and only the durable Add transactional approval and durable execution recovery #124 worker can invoke the todo writer./todonever invokes the model, plugin, approval flow, or task writer and returns only static conversational guidance./todoproduces no task.Test scenarios
Ordinary conversation and clarification
Given an active linked private user, fake z.ai responses, and requests with complete, missing, ambiguous, relative-date, exact-time, and multi-todo content
When #121 and #125 process each input
Then complete single input reaches one preview, missing/ambiguous values ask one question, relative dates show an exact Berlin date, time requests require date-only confirmation, multi-todo requests select none, and the task writer call count is zero.
Strict plugin schema
Given descriptions with whitespace/Unicode/control/zero-width/oversize variants, valid/invalid dates, arrays, extra fields, alternate assignees/statuses, and embedded instruction-like text
When
propose_createvalidates themThen only one normalized description plus real date is accepted, instruction-like description remains inert data, unsupported fields are rejected, and no invalid proposal/writer call exists.
Exact preview and revision
Given proposal v1 and revisions changing description or date
When previews are rendered and old/new controls are used
Then each preview/hash contains all current fields, v1 is superseded/revoked, v1 approval creates nothing, and only exact approval of the current version may queue one attempt.
Approval and actor isolation
Given active, disabled, revoked, unlinked, other-user, group, stale-plugin, expired, canceled, and detached-“yes” cases
When invocation or approval is attempted
Then only the exact active actor/private-channel/current-presentation path queues execution; every other case creates no attempt/task and reveals no other user's state.
Capability and field confinement
Given a malicious model/plugin candidate and direct writer calls containing owner/status/bundle/recurrence/time/link/update/delete/arbitrary fields
When validation and execution run
Then every extra capability is rejected, the writer exposes no generic task client, and a valid result contains only the fixed actor-owned todo fields and safe provenance.
Concurrent approval and execution
Given 25 simultaneous approval callbacks, duplicate Telegram updates/Stream records, and concurrent workers
When the full flow runs against DynamoDB Local
Then one proposal/attempt/task ID wins, one task row exists, all idempotent success paths report that same task, and the task contents equal the approved preview.
Conflict and authorization revocation
Given proposal revision/build/schema/policy/hash changes, deterministic task-ID collision with different data, identity disablement, permission revocation, and a stale worker lease
When approval/recovery runs
Then no mismatched task is created or overwritten, no stale worker dispatch succeeds, and the attempt records a safe conflict/failure requiring a fresh proposal where appropriate.
Crash and rollback boundaries
Given injected failure (a) before approval commit, (b) after approval before lease, (c) before task transaction, (d) during transaction, (e) after task commit before return, and (f) after return before attempt-result write
When #124 recovery runs
Then (a,c,d) leave no task, (b) eventually executes, and (e,f) find the exact existing deterministic task and finalize once without delete/recreate/duplicate.
Command and legacy bypass regression
Given
/todo,/todo buy milk tomorrow, and the legacy ordinary direct-task inputWhen the Telegram route processes them
Then commands return static guidance with zero model/writer calls, ordinary input enters conversation/preview, and no compatibility path creates a task before approval.
Export, restore, and redaction
Given ordinary tasks plus conversational todo tasks and malformed/secret-bearing assistant provenance
When portable export validation, dry-run import, and restore tests run
Then optional safe provenance round-trips, legacy tasks remain valid, unsafe provenance fails without echoing the value, and restored records cannot replay an approval.
Infrastructure permissions
Given the SAM template and deployed-role assertions
When validation runs
Then only the execution worker gains the required task
GetItem/conditionalPutItem/transaction access, while the model/runtime and Telegram webhook paths cannot write tasks directly through this plugin.Required verification
Software Engineer and Tester must run:
npm --prefix backend test npm --prefix backend run typecheck npm --prefix backend run build make sam-validate make sam-buildAlso run focused DynamoDB Local tests for plugin validation, actor isolation, 25-way approval concurrency, deterministic task collisions, lease enforcement, all crash boundaries, legacy bypass removal, and portable export/restore provenance. Use injected clocks/current Berlin date, fake z.ai, fake Telegram transport, and no external network or real provider write.
Run the existing Telegram, task API/data-layer, conversational runtime, approval/worker/recovery, portable export, restore, and SAM/IAM test suites in full. Assistant Engineer reviews the plugin/executor boundary before Tester acceptance.
No portal UI changes are in scope, so Playwright/screenshots are not required unless implementation unexpectedly changes a web surface; Tester must explain any omission. The real Telegram/task creation is only the single
[HUMAN]sandbox gate above. When all automated work passes first, ship withRefs #126, addhuman, and leave the issue open until that gate is complete.Dependencies
todo:create:self, strict two-turn loading/invocation, context/current-date input, z.ai model adapter, and stale-turn validation.Implementation must not weaken a dependency contract. If #121's final interface names differ, adapt this slice to its normalized private-message/action contracts without adding a second Telegram path.
Out of scope
/todomutation shortcut, slash-command parsing into a proposal, or command-based approval.AssistantJobapprovals.../dtc-operations,../datatasks, or../podcast-assistant.