Skip to content

Ship approved conversational todo creation #126

Open

Description

@alexeygrigorev

Ship approved conversational todo creation

Status: source implementation, independent verification, PM acceptance, commits, and original default-off deployment are complete; accepted #179/#168 canonical Task/Card follow-ups are committed on local main but unpushed/unshipped, and the only remaining #126 outcome is the HUMAN text/todo subset owned by #128 after #166/#182
Tags: enhancement, assistant, work-engine, backend, infra, testing, data, human, P1
Parent: #122
Depends on: #121/#124/#125 source and default-off prerequisites are satisfied; accepted #179 commit 02ee455efad09865ecdbd578e940c59e0bf7dc36 and #168 commit 41dca9e3748fe627c195f48a7f97ae203b343f60 define the canonical Task version/history and Card lifecycle contract and are local-only; live evidence waits for #166 A/B/C → #182 final preflight → D → cleanup and one ordinary all-off deploy
Blocks: live-acceptance closure only; #128 owns the integrated rollout and #126 is not a source blocker
Next owner: the #166 orchestrator/credentialed operator through the reviewed storage sequence; then the authorized HUMAN Telegram/provider owner with On-Call through #128; PM closes #126 after the bounded sanitized todo cross-post passes
Resume condition: #166/#182 record accepted sandbox outcomes, canonical writers reopen on the final empty Tasks schema with the accepted #179/#168 commits, temporary phase controls are deleted, ordinary push-triggered OIDC deployment is restored, and one normal main all-off run succeeds; then #128 may run its Text + todo stage
Architecture: _docs/CONVERSATIONAL_AGENT_PLUGIN_ARCHITECTURE.md at 4e5402c

Current review state

  • c47c5258a08b29c7c5ea6e797149c8a6619bbe71 and SAM portability follow-up c8d153cf1ddb07acca6846182b4f65af9338b6ff are accepted ancestors of origin/main. The static runtime registry/plugin, strict proposal, capability-limited writer, recovery, result delivery, tests, SAM resources, and default-off controls are source-complete.
  • Roll out and cut over the Telegram conversational MVP #128 rollout commit 9595361a0546a52a5cb90ace7df0bbdeb524866a is also integrated. Normal OIDC runs 31545689094 and 31711997388 reached successful all-off deploy/seed/smoke outcomes. This proves the dark path and fail-closed configuration; it is not a live Telegram, model, approval, or Task-write result.
  • Accepted Prevent lost Task updates and history with optimistic concurrency #179 commit 02ee455efad09865ecdbd578e940c59e0bf7dc36 makes every new todo Task canonical at version: 1 with taskHistory: []. Accepted Complete and archive cards automatically when all tasks are done #168 commit 41dca9e3748fe627c195f48a7f97ae203b343f60 keeps the todo writer and portable contract inside the strict canonical Task/Card lifecycle. Both are ancestors of current local main but absent from origin/main; neither is shipped or active in the sandbox.
  • No live Telegram todo journey, z.ai invocation, approval, Task creation, duplicate-delivery proof, or rollback has run.

#126 closure subset delegated to #128

After #166 repaired A/B/C → #182 final no-replacement Cards preflight → reviewed D → cleanup and one following ordinary all-off deployment:

  1. Enable only Roll out and cut over the Telegram conversational MVP #128 Text + todo through one normal OIDC stack update: Telegram ingress on, execution on, plugins exactly todo, Typefully external execution off, voice off, photo off.
  2. One linked active operator in a private Telegram chat sends an ordinary todo request, answers one missing/ambiguous-field clarification, requests one revision, and approves the exact current Berlin date-only preview. No Task may exist before that approval.
  3. Prove exactly one actor-owned Task and one private result. The Task must match the approved description/date and fixed status=todo, source=conversational-agent, actor ownership, safe assistant provenance, version=1, and taskHistory=[]; it must read cleanly under the accepted Prevent lost Task updates and history with optimistic concurrency #179/Complete and archive cards automatically when all tasks are done #168 canonical contract.
  4. Repeat the approval/delivery path and prove convergence on the same Task/result with no second Task. Send /todo and prove static guidance with no proposal, provider call, writer call, or Task.
  5. Cross-post only sanitized IDs/hashes, counts, states, and timestamps to Ship approved conversational todo creation #126. Do not post chat text, Telegram identity, secret/provider configuration, prompt/completion, or task contents beyond a synthetic/sanitized field-match statement.

This bounded text/todo proof is the only remaining #126 criterion. Live voice/photo, Typefully preview/effect, unrelated alarm canaries, and completion of the full #128 rollback matrix are not #126 closure requirements. A failed stage stops progression under #128; it does not authorize replay of an unknown effect, queue purge, Task deletion, manual Lambda patch, migration, import, export, or restore.

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.

Keep the first todo schema deliberately small:

description: required normalized plain text, 1–500 characters
date: required valid YYYY-MM-DD calendar date

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

  1. A linked, active user sends an ordinary message in a Telegram private chat, for example: “Remind me to follow up with Jane next Tuesday.”

  2. 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.

  3. The runtime loads the registered todo plugin in turn one and invokes its strict propose_create action in the separate turn two.

  4. The plugin asks only for missing or ambiguous description/date information. It never creates a task during clarification.

  5. The bot presents one normalized todo:

    Todo
    Task: Follow up with Jane
    Date: 2026-08-04 (Europe/Berlin, date only)
    Assignee: You
    Status: Todo
    
  6. Core controls are Approve todo, Request changes, Cancel proposal, and Discard draft.

  7. 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.

  8. 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.

  9. 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.

  10. 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:

id: todo
action: propose_create
effect: proposal
core permission: todo:create:self
delivery/recovery: deterministic idempotent create
allowed roles: admin, operator
allowed channel: telegram_private

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;
  • produce a pure candidate only; it cannot call task storage or Add transactional approval and durable execution recovery #124 approval/execution methods.

The immutable ProposalSpec binds:

  • plugin=todo, exact build/schema/policy digests, and action=propose_create;
  • operation=create, effect=task.create, and destination dataops.tasks;
  • normalized description and exact date;
  • fixed status=todo, source=conversational-agent, timeZone=Europe/Berlin;
  • 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:

  1. condition-check that the referenced Add transactional approval and durable execution recovery #124 attempt is still executing, belongs to this exact proposal/actor, has this payload hash, and is owned by the supplied unexpired lease generation;
  2. 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;
  • another actor's presentation or attempt;
  • stale conversation/plugin/draft revision;
  • expired/revoked/consumed/superseded presentation;
  • changed plugin/build/schema/policy/payload/rendered-view digest;
  • 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.
  • Crash or lost response after the task transaction commits: keep the task; Add transactional approval and durable execution recovery #124 recovery uses the same attempt/key, reads the deterministic task, and records success without another effect.
  • Crash before Add transactional approval and durable execution recovery #124 records the successful receipt: the same recovery behavior applies.
  • 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.
  • An ordinary private-chat request and confirmed media-derived text use the two-turn Build the static plugin runtime and z.ai conversational adapter #125 path; no task is created during selection, clarification, draft, preview, revision, or approval request handling.
  • Missing/ambiguous description/date, specific time, and multiple-task requests receive concise clarification without guessing or batching.
  • Relative dates use the supplied current Europe/Berlin date and the preview always displays an exact YYYY-MM-DD, timezone, and “date only” semantics.
  • Preview displays the complete normalized description, date, assignee, and status bound to the immutable proposal hashes.
  • Request changes supersedes the old proposal/presentations and shows a full revised preview; stale controls execute nothing.
  • Core approve/cancel/discard/expiry semantics are reused unchanged; plugins cannot approve themselves or define transitions.
  • Approval returns execution_pending, and only the durable Add transactional approval and durable execution recovery #124 worker can invoke the todo writer.
  • 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, delegated to Roll out and cut over the Telegram conversational MVP #128 Text + todo] After the Replace the transitional Tasks table with the final cardId schema #166/Gate canonical Card lifecycle on the empty production Cards table #182 sequence and a fresh ordinary all-off deployment, one linked operator sends an ordinary private Telegram todo request, answers one clarification, requests one revision, approves the exact preview, and confirms exactly one canonical matching Task exists. Repeated approval/delivery produces no second Task, while /todo invokes no provider/writer and produces no Task. Sanitized evidence is cross-posted here.

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

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.
  • Task update, delete, complete, waiting/follow-up, undo, recurrence, reminder times/notifications, another assignee, bundle/template linkage, tags, files, docs, proof, or arbitrary task fields.
  • Group conversations/topics, web conversation/approval, cross-channel continuation, or notification delivery beyond Consolidate private Telegram identity, text, voice, and photo input #121's Telegram result.
  • New voice/photo processing; Consolidate private Telegram identity, text, voice, and photo input #121 owns media conversion/confirmation and this issue consumes only confirmed derived text.
  • Typefully, SOP, podcast, GitHub, workflow, calendar, email, or other plugins/effects.
  • Personal memory, broad history/reference search, source-document retrieval, or private knowledge ingestion.
  • Changes to generic task product behavior beyond optional safe provenance compatibility and the dedicated internal todo writer.
  • Retrofitting legacy AssistantJob approvals.
  • Modifying ../dtc-operations, ../datatasks, or ../podcast-assistant.

Activity

  1. added
    enhancementNew or improved functionality
    needs groomingRaw intake that needs PM grooming
    assistantAssistant modules and jobs
    P1Important
    work-engineDataTasks task execution engine
    infraDeployment and infrastructure
    dataData model, migration, storage
    and removed
    needs groomingRaw intake that needs PM grooming
    on Jul 29, 2026
  2. alexeygrigorev commented on Jul 29, 2026

    @alexeygrigorev
    MemberAuthor

    GROOMED

    This issue is implementation-ready after #121, #124, and #125 close.

    Key product decisions:

    • Exactly one actor-owned todo with only normalized description and exact date; status, ownership, source, and Berlin timezone are core-owned.
    • Ordinary private conversation only. The /todo command returns static guidance and never invokes the model or writer.
    • Missing or ambiguous dates ask; specific times require explicit date-only confirmation; multiple requested todos are not batched.
    • Revision creates a new immutable preview and invalidates old controls. Core approval queues durable execution; the webhook never writes the task.
    • A dedicated ActorTodoWriter uses a deterministic task ID and a DynamoDB transaction that condition-checks the current attempt lease before conditional task creation. It exposes no generic task CRUD.
    • Post-commit lost responses reconcile the same task rather than deleting or duplicating it. Pre-write and transaction failures leave no task.
    • Added actor isolation, strict-schema, stale-control, 25-way concurrency, idempotency collision, authorization revocation, six crash-boundary, rollback/recovery, export/restore, legacy bypass, SAM, and least-privilege tests.
    • Only one real deployed Telegram/task check remains HUMAN; all other verification is automated with fakes and DynamoDB Local.
  3. alexeygrigorev commented on Jul 30, 2026

    @alexeygrigorev
    MemberAuthor

    Software Engineer handoff

    Implemented the approved conversational todo creation slice without committing or pushing.

    What changed

    • Registered one production todo.propose_create plugin with the strict two-field candidate, Berlin date-only policy, static /todo guidance, and no direct effect.
    • Added a shared proposal coordinator/adapter seam and per-request plugin visibility so later channel capabilities can reuse proposal/session handling without exposing every plugin.
    • Added the generic conversational proposal core integration for ordinary private Telegram text, revision previews, exact bound controls, stale-action rejection, and detached-text approval rejection.
    • Added a capability-limited ActorTodoWriter/executor. It derives a deterministic task ID and uses one DynamoDB transaction to condition-check the live attempt lease/proposal/actor/hash and conditionally create the fixed actor-owned task.
    • Added strong-read collision/lost-response reconciliation, safe task provenance, portable task validation, and removal of the legacy direct-task compatibility write.
    • Added atomic terminal-attempt + owner-private-result + delivery-notification finalization. A dedicated scheduled Telegram dispatcher rechecks identity/channel ownership and never retries ambiguous or post-claim delivery outcomes.
    • Added 30-day result retention and portable export handling that redacts private result text, omits Telegram destinations, and makes undelivered notifications non-replayable.
    • Added least-privilege task permissions to the execution worker and a separate least-privilege dispatcher role owning only state read/update and the exact Telegram secret.

    Primary files:

    • backend/src/conversation/{todoPlugin,proposalCoordinator,todoCore,todoWriter,resultDispatcher}.ts
    • backend/src/conversation/{execution,executionDefaults,executionRepository,executionWorker,plugins,portable,repository,runtime,telegramAdapter,types}.ts
    • backend/src/result-notification-handler.ts
    • backend/src/routes/{telegram,conversationalExecution}.ts
    • backend/src/{execution-worker-handler,types}.ts
    • backend/src/export/portable.ts
    • backend/tests/{todo-conversational,conversational-runtime,telegram-conversational,telegram,export-portable}.test.ts
    • backend/scripts/test-todo-transaction.sh
    • infra/template.full.yaml, tests/infra/test_template.py, Makefile, backend/README.md, backend/package.json

    Verification

    • npm --prefix backend test — PASS: 1,313 passed, 0 failed, 1 intentional Docker-only skip (1,314 total).
    • npm --prefix backend run typecheck — PASS.
    • npm --prefix backend run build — PASS.
    • npm --prefix backend run test:todo-transaction — PASS: 6/6 against genuine DynamoDB Local, including 25 concurrent writer deliveries, 25 approvals/workers, deterministic collision/lost-response recovery, atomic outbox, owner isolation, duplicate delivery, ambiguous send, post-claim crash, and retention.
    • npm --prefix backend run test:execution-transaction — PASS: 1/1 against genuine DynamoDB Local with 25 concurrent approvals.
    • npm --prefix backend run test:telegram-transaction — PASS: 3/3 against genuine DynamoDB Local.
    • .venv/bin/python -m pytest tests/infra/test_template.py -q — PASS: 25/25.
    • Focused private Telegram adapter test after the final portable-export assertion — PASS: 16/16.
    • make sam-validate — PASS.
    • make sam-build — PASS; all three functions packaged successfully.
    • git diff --check — PASS.
    • Credential scan for the supplied Telegram token/prefix in tracked work — PASS, not present.

    No portal UI changed, so Playwright/screenshots are not applicable. No provider/network mutation or real Telegram message was sent.

    Acceptance status

    All automatable acceptance criteria are implemented and covered by the full/focused suites above. The remaining [HUMAN] sandbox Telegram/task-creation gate is intentionally pending; the issue must remain open and the eventual commit should use Refs #126.

    READY FOR ASSISTANT ENGINEER AND TESTER REVIEW.

  4. alexeygrigorev commented on Jul 30, 2026

    @alexeygrigorev
    MemberAuthor

    ASSISTANT ENGINEER — CHANGES REQUESTED

    The narrow writer/idempotency design is good, the generic coordinator seam is reusable for #127, and the production-style DynamoDB Local flow passes. I cannot pass the boundary yet because the following safety contracts are not implemented end to end.

    1. Time/date-only confirmation and multi-todo rejection are model instructions, not trusted state

    todoPlugin.ts validates only the two returned fields. It accepts, for example, {description: "Call Jane at 09:00", date: "2026-08-04"} and also accepts a description containing multiple requested actions. The only protection is prose in skillInstructions. The validator cannot know that the model silently dropped a requested time/reminder or selected one item from a multi-todo source message.

    This does not meet the issue's deterministic requirements that a specific time requires explicit date-only confirmation and that multiple requested todos select none. Bind those decisions in core-owned draft state (or another trusted, typed confirmation mechanism) and make proposal creation fail closed unless the stored source/request state proves one task and, where applicable, an explicit date-only confirmation. Add incorrect/malicious fake-z.ai cases that attempt to omit the time or collapse a batch.

    2. Permission visibility and revocation are not exact enough

    • The production registry always exposes todo to every admin/operator Telegram catalog. ConversationalProposalCore does not compute a permission-scoped availablePluginIds list in its default path, so an actor lacking todo:create:self sees/loads the skill and reaches the model before the invocation-time permission rejection. The issue says the plugin is visible and invocable only with that permission.
    • getApprovalPermission, getIdentityBinding, and getChannelBinding use eventually consistent reads. No permission revision is stored in the draft/proposal/attempt.
    • Most importantly, the todo writer transaction condition-checks only the execution attempt. Revocation/disablement/binding replacement can occur after preDispatchCheck and before ActorTodoWriter.write; the task still commits. The approval transaction is atomic, but it cannot protect a revocation that occurs after approval and before execution.

    Make visibility permission-scoped before the first model turn. Bind the authorization revision(s) needed by the proposal/attempt, use strong reads where "current" is required, and include current user/permission/identity/channel conditions in the effect transaction (or an equivalent atomic authorization epoch condition) so a revocation cannot race the task write. Add a genuine DynamoDB race test that revokes between preflight and the task transaction.

    3. Async result delivery does not revalidate the exact owner binding or enabled user

    The notification stores only actor, channel, conversation, and channelConversationKey; it omits the attempt's identityChannelUserId, identityBindingId, and channelBindingId/revisions. The dispatcher then calls:

    getIdentityBinding(channel, channelConversationKey)

    This assumes a Telegram chat ID is the identity's user ID instead of checking the stored identity key. It also never loads the DataOps user, so a disabled user can still receive a private result. The dispatcher IAM has no Users-table read permission, which confirms that check cannot happen in production. A replaced/rebound binding is accepted as long as actor/conversation happen to match; exact binding revision is not checked.

    Persist safe binding references from the approved attempt, then immediately before send strongly revalidate the enabled DataOps user, exact active identity binding, exact private channel binding, actor, and conversation. Keep the executor free of the Telegram secret. Add disabled-user, revoked/replaced identity, replaced channel binding, and chat-ID-vs-user-ID tests. Also pass Telegram chat_id as the validated string rather than converting the accepted 20-digit value through Number, which can lose precision and address the wrong destination.

    4. Capability rollout is not independently default-off

    todoPluginDefinition.enabled is hard-coded true, defaultExecutionRegistry always registers ActorTodoExecutor, and the result dispatcher schedule is always enabled. The global conversational Telegram flag protects the webhook, but there is no plugin/executor/result-delivery flag or managed plugin configuration as required by the architecture's enable/disable contract. Add exact default-false rollout controls used consistently by catalog visibility, proposal creation, executor registration/recovery, and result dispatch. Ensure existing claimed attempts have an explicit safe deployment policy rather than becoming executable through a newly registered capability accidentally.

    5. Missing composed media acceptance proof

    The existing Telegram tests prove voice/photo confirmation with a fake core, and the todo test proves the two-turn flow by calling the todo core directly with text. There is no composed test proving confirmed voice- or photo-derived text enters the real two-turn todo proposal path while unconfirmed/canceled media cannot create a proposal/task. Add at least one confirmed photo and one confirmed voice journey through the production adapter/core composition, including stale/cross-actor controls and writer count zero before approval.

    Verification performed

    • npm --prefix backend run test:todo-transaction — PASS, 6/6, including the DynamoDB Local 25-way approval/worker flow and production atomic outbox branch.
    • npm --prefix backend test ... — PASS, 1,313 passed / 1 intentional Docker-only skip. (The package script ran the full suite.)
    • npm --prefix backend run typecheck — PASS.
    • make sam-validate — PASS.

    No implementation files were changed, committed, or pushed during this review.

  5. alexeygrigorev commented on Jul 30, 2026

    @alexeygrigorev
    MemberAuthor

    Software Engineer revision handoff

    Addressed every blocker from the Assistant Engineer review. No commit or push was made.

    Review blockers resolved

    1. Trusted time and multi-todo decisions

      • Added deterministic source classification before any model call.
      • Specific-time/reminder inputs require the exact confirm date only response against current core-owned draft state.
      • Multi-todo inputs select nothing and cannot be collapsed by a malicious/malformed model candidate.
      • The immutable proposal binds a source proof and validated draft reference; the writer rejects missing or altered proof.
    2. Permission visibility and revocation safety

      • Plugin catalog visibility is permission-scoped before the first model turn; unauthorized callers produce zero model calls.
      • Permission, identity, channel, conversation, and user reads used for current authorization are strongly consistent.
      • Proposal and attempt bind the permission revision.
      • The task effect transaction condition-checks the exact enabled user role, permission revision, identity binding revision, channel binding, active conversation owner, worker lease, proposal, actor, and payload hash together with conditional task creation.
      • A genuine DynamoDB Local race revokes permission after preflight and before the transaction and proves no task is created.
    3. Exact private result ownership

      • Notifications bind the exact identity user ID, identity binding ID/revision, channel binding ID, actor, and conversation.
      • The dispatcher strongly revalidates the enabled DataOps user, exact active identity binding, exact private channel binding, actor, and conversation immediately before send.
      • Telegram chat_id remains a validated string, including 20-digit IDs.
      • IAM now grants the dispatcher only the additional Users-table read it needs; the executor still has no Telegram secret.
      • Tests cover disabled user, replaced identity, replaced channel binding, and distinct Telegram user/chat identifiers.
    4. Independent default-off rollout

      • Added separate plugin, executor, and result-delivery flags, all default false in code, SAM, and deployment workflow.
      • Catalog/proposal requires plugin and executor enablement, executor registration is independently gated, and the result schedule/handler are independently gated.
      • If the executor is absent, claimed attempts use the existing deterministic failed-safe pre-dispatch path rather than becoming executable accidentally.
    5. Composed voice and image proof

      • Added a Docker/DynamoDB Local composition test using fake Telegram/media providers but the real production adapter, real todo core, approval coordinator, durable worker, private result outbox, and dispatcher.
      • Voice and image-derived text remain inert before explicit use; discard, stale, replay, and cross-actor controls create no proposal/task.
      • Confirmed voice reaches approval and creates exactly one task only after approval. Confirmed image reaches the real proposal path with zero writer calls before approval.

    Verification

    • npm --prefix backend run typecheck — PASS.
    • npm --prefix backend run test:todo-transaction — PASS: 9/9 against genuine DynamoDB Local, including composed voice/image, 25-way approval/writer concurrency, revocation race, collision, recovery, and result delivery.
    • npm --prefix backend test — PASS: 1,315 passed, 0 failed, 1 intentional Docker-only skip (1,316 total).
    • npm --prefix backend run test:execution-transaction — PASS: 1/1 against genuine DynamoDB Local.
    • npm --prefix backend run test:telegram-transaction — PASS: 3/3 against genuine DynamoDB Local.
    • uv run --with pytest python -m pytest -q tests/infra — PASS: 27/27.
    • npm --prefix backend run build — PASS.
    • make sam-validate — PASS.
    • make sam-build — PASS; all three Lambda functions packaged.
    • git diff --check — PASS.
    • Generic Telegram bot-token pattern scan of tracked diffs and untracked issue files — PASS, none found.

    No web UI changed, so Playwright/screenshots are not applicable. No real provider, Telegram, task, deployment, commit, or push mutation was performed. The remaining [HUMAN] sandbox Telegram gate stays pending, so the eventual commit must use Refs #126.

    READY FOR ASSISTANT ENGINEER RE-REVIEW AND TESTER.

  6. alexeygrigorev commented on Jul 30, 2026

    @alexeygrigorev
    MemberAuthor

    ASSISTANT ENGINEER RE-REVIEW — CHANGES REQUESTED

    The revision materially closes the five original safety findings:

    • todo visibility is permission-scoped before the first model call;
    • time/multi-request guards are core-owned and proposal-bound;
    • permission/identity revisions are bound and the task transaction atomically rechecks user, permission, identity, channel, conversation, lease, actor, and payload;
    • result dispatch revalidates the exact identity key/revision, channel binding, enabled user, actor, and conversation, and keeps Telegram chat IDs as strings;
    • plugin, executor, and result delivery are independently default-off in code, SAM, and deployment configuration;
    • the genuine DynamoDB harness composes confirmed media with the real adapter/core and proves task/outbox delivery for voice.

    One architecture blocker and one required proof gap remain.

    1. The generic coordinator stops working as soon as a second plugin is enabled

    ConversationalProposalCore.handle initializes sourceAdapter/sourceProof only inside:

    if (availablePluginIds.length === 1) {
      // choose adapter and run preflight
    }

    After the model selects and invokes a plugin, the core unconditionally requires:

    if (!sourceAdapter || sourceAdapter.pluginId !== adapter.pluginId || sourceProof === null) {
      return this.error();
    }

    Therefore, when #127 enables both todo and typefully, the compact catalog can contain both and the model can select one, but every proposal is rejected because sourceAdapter stayed null. A request-level contextProvider.availablePluginIds filter does not repair this: source preflight runs before that filter and still sees the full enabled adapter list.

    Move plugin-specific source preflight to a point where the selected plugin is known while preserving the required pre-model/candidate safety boundary—for example, a bounded core selection/preflight phase between skill_load and skill_invoke, or another generic coordinator hook that cannot be bypassed by model candidate output. Add a test with two enabled proposal adapters proving each can be selected, preflighted, proposed, revised, and approved without todo-specific branching in the core. This is the required #127 reusable seam, not a future enhancement.

    2. The composed image journey stops at preview

    todo-media-composed.test.ts takes voice through approval, worker execution, private outbox, and dispatch. The photo branch confirms derived text and reaches a real preview with zero pre-approval writes, but it never approves that preview or verifies worker/task/private-result delivery. The requested re-review gate explicitly includes voice and photo through approval/worker/private result. Complete the photo branch through the same durable boundary and assert one exact task/result, duplicate/stale approval safety, and no media bytes/Telegram identifiers in task provenance or safe receipt.

    Verification performed

    • npm --prefix backend run typecheck — PASS.
    • npm --prefix backend run test:todo-transaction — PASS, 9/9 against genuine DynamoDB Local.
    • uv run --with pytest python -m pytest -q tests/infra — PASS, 27/27.
    • make sam-validate — PASS.
    • npm --prefix backend run build — PASS.
    • git diff --check — PASS.

    No implementation files were edited, committed, or pushed during this review.

  7. 10 remaining items

  8. added
    humanCode done or issue blocked on human verification
    on Jul 30, 2026
  9. alexeygrigorev commented on Jul 30, 2026

    @alexeygrigorev
    MemberAuthor

    Software Engineer handoff — native SAM transform portability regression fixed

    Fixed the repository-owned failure in Validate Planning Docs run
    https://github.com/DataTalksClub/dataops/actions/runs/30532699890 on pushed
    main c47c5258a08b29c7c5ea6e797149c8a6619bbe71. The change is isolated in
    branch hotfix-126-sam-portability, remains intentionally uncommitted and
    unpushed, and is ready for independent Tester review.

    Root cause and fix

    tests/infra/test_template.py treated shutil.which("sam") as UTF-8 source and
    used its first line as a Python interpreter. That worked for pip/uv SAM wrappers
    but setup-sam's recommended native installer provides an ELF executable, so CI
    failed with UnicodeDecodeError before any transform.

    The test now:

    • reads at most the executable's first line as bytes;
    • invokes a shebang wrapper through its declared interpreter and invokes a
      native executable directly;
    • runs the actual installed SAM CLI's validate --debug transform twice, once
      with the production default-off template and once with an isolated
      explicit-true parameter-default variant under the repository-local .tmp/;
    • extracts SAM's real translated template and asserts the generated
      AWS::Events::Rule, the exact
      Fn::If [ConversationalResultDeliveryIsEnabled, ENABLED, DISABLED] state,
      the exact equality condition, and the transformed false/true defaults;
    • adds executable-launch regression coverage for both a real Python shebang
      script and the native Python ELF used by the test process.

    There is no binary-path skip and no replacement with a static-only assertion.

    Changed file

    • tests/infra/test_template.py

    Tracked diff fingerprint:
    9ccfc0fa59b0253419c22a4728e38115c6fb80396d23707a4e88469a92313f78

    Verification

    • Local pip/uv shebang SAM focused portability/transform tests — PASS, 3/3.
    • Actual AWS SAM native-installer v1.164.0 Linux x86_64 ELF focused tests —
      PASS, 3/3.
    • PATH=<native-sam-dist> uv run --with pytest python -m pytest tests/infra —
      PASS, 35/35.
    • make validate-planning-docs — PASS, 7/7.
    • Native make sam-validate with empty local AWS config/credentials —
      PASS.
    • Native sam validate --template-file infra/template.full.yaml --lint with
      empty local AWS config/credentials — PASS.
    • Native make sam-build — PASS; all six functions packaged.
    • npm --prefix backend test after the required clean npm ci in the isolated
      worktree — PASS, 1,375 passed, 1 intentional transaction-harness skip,
      0 failed
      .
    • npm --prefix backend run typecheck — PASS.
    • git diff --check, single-file scope, conflict/credential-pattern scan —
      PASS.

    The first proportional backend run before npm ci reported only a missing
    local @aws-sdk/client-sesv2 package; installing the locked dependencies and
    rerunning the complete suite produced the clean result above. No product file
    was changed for that environment setup.

    No portal/frontend behavior changed, so screenshots and Playwright are not
    applicable. No commit, push, deploy, AWS mutation, provider call, or Telegram
    message was performed. Existing #126 HUMAN gates remain unchanged; an eventual
    commit must continue to use Refs #126 and leave the issue open.

  10. alexeygrigorev commented on Jul 30, 2026

    @alexeygrigorev
    MemberAuthor

    On-Call report — main c47c525 (Refs #126)

    Both workflows triggered for c47c5258a08b29c7c5ea6e797149c8a6619bbe71 reached terminal failure, for two independent and precisely classified reasons. No manual deploy, AWS mutation, provider call, or Telegram action was performed by On-Call.

    1. Repository/application checks and packaging

    Deploy DataOps V1 Lambda run 30532699861 completed its Check DataOps v1 app job successfully in 5m18s:

    • backend: 1,375 passed, 1 intentional transaction-harness skip, 0 failed (1,376 total; 191 suites);
    • backend typecheck: PASS;
    • backend build: PASS;
    • Playwright: 352/352 passed;
    • SAM template validation: PASS;
    • SAM build: PASS.

    The successful check build packaged exactly the relevant six functions, including:

    • ConversationalExecutionWorkerFunction;
    • ConversationalResultDispatcherFunction;
    • SponsorSendWorkerFunction;
    • SponsorSesEventFunction;
    • SponsorPrivateArchiveFunction;
    • BackendFunction.

    The deploy job independently rebuilt the same six functions and ended with Build Succeeded before calling CloudFormation. This is direct CI evidence that the new worker and dispatcher compile and package on the GitHub runner.

    The ordinary backend CI command deliberately skips the Docker/DynamoDB Local transaction harness; this run therefore is not new CI execution evidence for those dedicated suites. The accepted current-tree Tester evidence remains: todo 10/10, execution 1/1, Telegram 4/4, sponsor finance 16/16, and sponsor communications 19/19: #126 (comment). Adding the dedicated transaction commands to CI is a separate coverage decision; this report does not misrepresent the one skipped test as executed in Actions.

    2. Code/test portability regression in the second workflow

    Validate Planning Docs run 30532699890 failed before any AWS operation. SOP lint and planning-doc validation passed, but tests/infra finished 32 passed, 1 failed.

    The failing #126 transform test at tests/infra/test_template.py:202 calls Path(shutil.which("sam")).read_text(...) to extract a Python shebang. aws-actions/setup-sam@v3 installs a native ELF sam binary in CI, so the read raises UnicodeDecodeError before the transform assertion runs. This is a repository-owned portability defect, not IAM, AWS, z.ai, Telegram, or a flaky assertion. It must be corrected by Software Engineer and re-run; On-Call did not edit or push feature code.

    3. AWS deployment and terminal rollback

    The deploy job successfully configured OIDC credentials, passed its second SAM build, and invoked the normal sam deploy path with all three #126 rollout flags resolving to false:

    • ConversationalTodoPluginEnabled=false;
    • ConversationalTodoExecutorEnabled=false;
    • ConversationalResultDeliveryEnabled=false.

    CloudFormation then received the same live-role denials already covered by accepted but unapplied DataTalksClub/aws-infra source at 2a1b95f:

    The dispatcher role reached CREATE_IN_PROGRESS, then was cancelled by the primary failures and deleted during rollback. The dispatcher function, schedule, and live default-disabled state were therefore not created or verified. No separate dispatcher-policy denial was reached, so this run is not direct live #130 acceptance evidence.

    The stack ended cleanly at terminal UPDATE_ROLLBACK_COMPLETE. Runtime seeding and deployed-backend smoke tests were skipped. This is an external live-IAM prerequisite failure, not an application build/package regression.

    Required next actions

    1. Software Engineer fixes the native-binary SAM transform-test portability defect and ships a reviewed Refs #126 follow-up.
    2. A credentialed operator applies the accepted combined dataops-github-actions stack from DataTalksClub/aws-infra 2a1b95f with CAPABILITY_NAMED_IAM, and verifies the effective Add transactional approval and durable execution recovery #124/Repair DataOps OIDC SES configuration-set tag-on-create permission #129/Repair dispatcher generated-role IAM prefix for CloudFormation rollback #130 attachments. Do not replace normal DataOps CI/CD with a manual app deployment.
    3. Re-run through a fresh main push. Require both workflows green, the default-off deployment successful, and On-Call inspection of the dispatcher function/role/log graph plus disabled result-delivery rule.
    4. The real linked-user Telegram todo journey remains a later HUMAN gate.

    #126 remains open with the human label. The issue must not close until the external apply/deploy and live Telegram criteria pass.

  11. alexeygrigorev commented on Jul 30, 2026

    @alexeygrigorev
    MemberAuthor

    TEST PASS — native SAM portability hotfix fixes run 30532699890 without weakening the transform contract

    I independently reviewed and tested the uncommitted one-file hotfix in hotfix-126-sam-portability. I did not edit product/test source, commit, push, deploy, call AWS/Telegram/z.ai, or perform PM acceptance.

    Reviewed state and root cause

    • Base: c47c5258a08b29c7c5ea6e797149c8a6619bbe71.
    • Only changed path: tests/infra/test_template.py.
    • Initial/final tracked diff fingerprint: 9ccfc0fa59b0253419c22a4728e38115c6fb80396d23707a4e88469a92313f78.
    • Validate Planning Docs run https://github.com/DataTalksClub/dataops/actions/runs/30532699890 failed 1/33 infra tests because the test read setup-sam's \x7fELF... executable as UTF-8 and raised UnicodeDecodeError before invoking SAM. The other 32 tests passed.

    Hotfix contract

    • Native and wrapper launch: PASS. _executable_command reads only the first line as bytes, directly returns native executables, and replays a UTF-8 shebang as an argv list. There is no shell=True, shell interpolation, or shlex evaluation. A Python shebang with its single optional interpreter argument executes correctly; a native ELF executes directly.
    • No injection: PASS. An independent probe used a script filename and arguments containing spaces, semicolons, and $(...); argv remained literal and no sentinel file was created. Invalid UTF-8 shebangs fail with an assertion.
    • Actual transform retained: PASS. The test invokes the installed SAM CLI's real validate --debug transform for two project-local .tmp template variants. It does not import SAM internals, skip binary SAM, or replace the transform with a static source check.
    • Exact generated semantics: PASS. Both transformed templates contain the generated AWS::Events::Rule, exact Fn::If [ConversationalResultDeliveryIsEnabled, ENABLED, DISABLED] state, and exact Fn::Equals [Ref ConversationalResultDeliveryEnabled, 'true'] condition. The production variant has default 'false'; the isolated explicit-on variant has default 'true'.
    • Fail closed: PASS. Missing SAM debug marker raises the intended assertion, a false translated payload cannot satisfy the generated-rule lookup, non-zero SAM exits fail via check=True, and the true variant can only be produced after the expected production Default: "false" block is found and changed in the scratch copy.
    • Telemetry/credentials: PASS. Transform runs set SAM_CLI_TELEMETRY=0, disable EC2 metadata, and point AWS config/credentials at empty scratch paths.

    Commands and results

    • uv run --with pytest python -m pytest -vv tests/infra/test_template.py -k 'conversational_result_delivery_schedule or sam_executable_command' with the local pip/uv shebang SAM — PASS, 3/3 selected.
    • Downloaded official aws/aws-sam-cli release v1.164.0; file dist/dist/sam proves an x86-64 ELF and sam --version reports 1.164.0.
    • The same focused command with that native SAM first on PATH — PASS, 3/3 selected.
    • PATH=<native-sam-dist> uv run --with pytest python -m pytest -q tests/infra — PASS, 35/35.
    • Independent inline argv/security/debug fail-closed probe — PASS (ARGV_SECURITY_AND_FAIL_CLOSED: PASS).
    • make validate-planning-docs — PASS, 7/7.
    • PATH=<native-sam-dist> ... make sam-validate with empty AWS config/credentials and metadata/telemetry disabled — PASS.
    • PATH=<native-sam-dist> ... sam validate --template-file infra/template.full.yaml --lint — PASS.
    • PATH=<native-sam-dist> ... make sam-build — PASS; all six functions packaged: conversational execution worker, sponsor send worker, sponsor SES event, sponsor private archive, conversational result dispatcher, and backend.
    • npm --prefix backend test — PASS, 1,375 passed, 1 intentional genuine-transaction harness skip, 0 failed (1,376 total).
    • npm --prefix backend run typecheck — PASS.
    • npm --prefix backend run build — PASS.
    • git diff --check; single-path/base/hash assertions; conflict-marker scan; Telegram token, AWS key, private-key, GitHub-token, and generic credential-pattern scan — PASS.

    No UI/page behavior changed, so Playwright and screenshots are not applicable. Existing #126 HUMAN gates are unchanged: the credentialed deploy-role stack application and live private Telegram todo journey remain external checks. The eventual commit must continue to use Refs #126, retain human, and leave the issue open.

  12. alexeygrigorev commented on Jul 30, 2026

    @alexeygrigorev
    MemberAuthor

    PM ACCEPTED — native SAM portability hotfix

    I accept the frozen one-file hotfix for the Software Engineer commit gate.

    • Reviewed base: c47c5258a08b29c7c5ea6e797149c8a6619bbe71.
    • Only changed path: tests/infra/test_template.py.
    • Exact tracked diff fingerprint: 9ccfc0fa59b0253419c22a4728e38115c6fb80396d23707a4e88469a92313f78.
    • The fix directly addresses the observed GitHub Actions failure: a native setup-sam ELF is launched as an executable, while the existing pip/uv shebang form remains supported. It does not add a binary-path skip or substitute a static source assertion.
    • The product safety contract remains real and fail-closed. The test runs the installed SAM CLI's actual validate --debug translation for both the production default-off template and an isolated explicit-true scratch variant; both must contain the generated Events rule, the exact Fn::If [ConversationalResultDeliveryIsEnabled, ENABLED, DISABLED] state, and the exact equality condition, with translated defaults proven as false and true. Missing translation markers/resources/semantics, a non-zero SAM exit, or inability to construct the expected true scratch variant fails the test.
    • Scratch material stays in repository-local .tmp, telemetry and metadata lookup are disabled, and no credential/config fixture is inherited for the transform. No product/runtime/UI behavior, deployment configuration, or unrelated file is changed.
    • Independent Tester evidence passes the hotfix with both shebang SAM and an official native SAM v1.164.0 ELF, 35/35 infrastructure tests, planning validation, native SAM validate/lint/build, 1,375 backend tests plus the intentional transaction-harness skip, typecheck/build, security/fail-closed probes, and scope/diff scans: Ship approved conversational todo creation #126 (comment). Screenshots are not applicable to this test-only portability fix.

    Shipping instruction: commit this exact tree unchanged with Refs #126 (not Closes #126), retain the human label, and leave #126 open. After the normal local merge and main push, On-Call must monitor fresh CI/CD. The credentialed deploy-role stack apply, successful default-off deployment/runtime inspection, and live Telegram todo journey remain HUMAN gates; this acceptance does not claim them complete.

    No file, commit, push, deploy, AWS mutation, provider call, or Telegram action was performed during this PM review.

  13. alexeygrigorev commented on Jul 30, 2026

    @alexeygrigorev
    MemberAuthor

    On-Call report — SAM portability follow-up c8d153c (Refs #126)

    All workflows triggered by pushed main commit c8d153cf1ddb07acca6846182b4f65af9338b6ff are terminal.

    Fresh push evidence

    Validate Planning Docs run 30533952036 completed success in 35 seconds.

    The exact regression path is fixed on the GitHub-hosted runner:

    • aws-actions/setup-sam@v3 used its native installer and restored AWS SAM CLI 1.164.0;
    • uv run --with pytest python -m pytest tests/infra collected and passed 35/35 tests in 2.93 seconds;
    • tests/infra/test_template.py passed all 33 of its tests, including the real default-off and explicit-true SAM transform contract;
    • there is no UnicodeDecodeError, ELF decode attempt, skip, or weakened static-only replacement;
    • planning tests passed 7/7;
    • SOP lint passed 238 files;
    • knowledge-repository scaffold and docs-link/workflow-ID validation passed.

    The only annotation is the non-blocking GitHub Actions Node 20 deprecation warning. It did not affect the run.

    Application and deployment classification

    This test-only path triggered only Validate Planning Docs; it did not trigger a fresh Deploy DataOps V1 Lambda workflow. Therefore this report does not claim a fresh application build or deployment.

    The immediately preceding Deploy run 30532699861 remains the applicable application/package evidence for the unchanged product tree: its Check DataOps v1 app job passed backend 1,375 plus 1 intentional transaction-harness skip, typecheck, build, Playwright 352/352, SAM validation, and SAM build; the deploy job also rebuilt all six functions successfully.

    That preceding deploy then ended at terminal UPDATE_ROLLBACK_COMPLETE only after the already-classified live-role denials for sqs:CreateQueue and ses:CreateConfigurationSet. Accepted permission source exists in DataTalksClub/aws-infra at 2a1b95f for #124/#129/#130, but a credentialed operator has not yet proven the named-IAM stack applied. The dispatcher resource was cancelled during rollback, so there is still no live dispatcher graph or default-disabled rule evidence. No new IAM denial or new live evidence was produced by this test-only push, so no duplicate IAM issue comments were added.

    Status and handoff

    On-Call performed no code edit, commit, push, manual deploy, AWS mutation, provider call, or Telegram action.

  14. alexeygrigorev commented on Jul 31, 2026

    @alexeygrigorev
    MemberAuthor

    PM STATUS RECONCILIATION — todo code and portability fix complete; live journey pending

    PM decision: keep #126 open with human. After normal deployment can proceed,
    a linked operator must complete the single unchecked Telegram todo journey,
    including clarification, revision, exact approval, exactly one matching task,
    duplicate-approval idempotency, and /todo producing no task. No live Telegram,
    z.ai, task-creation, or provider success is claimed.

    No code, AWS, IAM, workflow, environment, Telegram, z.ai, or other provider
    action was performed during this reconciliation.

  15. removed
    humanCode done or issue blocked on human verification
    on Jul 31, 2026
  16. alexeygrigorev commented on Jul 31, 2026

    @alexeygrigorev
    MemberAuthor

    PM tracker reconciliation — todo rollout dependency corrected

    The accepted implementation remains on main. Replaced the stale #141 chain with #140 lifecycle acceptance plus #143 ownership remediation, recorded the #128 On-Call→authorized-HUMAN sequence and exact deployment resume signal, and removed the premature human label while agent/deploy gates remain. No Telegram action or criterion completion occurred.

  17. added
    humanCode done or issue blocked on human verification
    on Aug 13, 2026
  18. alexeygrigorev commented on Aug 13, 2026

    @alexeygrigorev
    MemberAuthor

    PM lifecycle reconciliation — source/default-off complete; HUMAN todo subset stays in #128

    The stale #136/#143 dependency has been removed. #126 implementation commit c47c5258a08b29c7c5ea6e797149c8a6619bbe71 and portability follow-up c8d153cf1ddb07acca6846182b4f65af9338b6ff are accepted ancestors of origin/main; #128 rollout source is integrated, and normal OIDC runs 31545689094 and 31711997388 prove the all-off deploy/seed/smoke path. They do not prove a live Telegram/model/task effect.

    The Task contract has moved forward safely. Accepted #179 commit 02ee455efad09865ecdbd578e940c59e0bf7dc36 adds canonical version: 1 / taskHistory: [] creation, and accepted #168 commit 41dca9e3748fe627c195f48a7f97ae203b343f60 keeps the todo path inside the strict Task/Card lifecycle and portable contract. Both are exact ancestors of current local main, but neither is on origin/main or active in the sandbox. No compatibility, migration, import, export, or restore path is needed.

    The remaining closure path is now exact and owned by #128:

    1. Complete Replace the transitional Tasks table with the final cardId schema #166 repaired A/B/C, Gate canonical Card lifecycle on the empty production Cards table #182 final read-only Cards preflight, reviewed D, cleanup, and one following ordinary all-off deployment with canonical writers open.
    2. Run only Roll out and cut over the Telegram conversational MVP #128 Text + todo through normal OIDC.
    3. Prove clarification → revision → exact approval → one canonical actor-owned Task/private result; repeated approval/delivery converges on the same Task; /todo invokes neither provider nor writer and creates nothing.
    4. Cross-post sanitized evidence here; then PM may close Ship approved conversational todo creation #126.

    Voice/photo, Typefully, unrelated alarm canaries, and the rest of #128 are not #126 closure requirements. #126 remains open with human. No repository edit, test, AWS/Telegram/provider call, deployment, credential access, data operation, dispatch, import, export, migration, or restore was performed in this reconciliation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1ImportantassistantAssistant modules and jobsbackendBackend/APIdataData model, migration, storageenhancementNew or improved functionalityhumanCode done or issue blocked on human verificationinfraDeployment and infrastructuretestingTests and QAwork-engineDataTasks task execution engine

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions