Files
FamReynaBrain/projects/pipecatvoice_kanban_postmortem_2026-08-10.md
T
2026-09-14 22:38:47 -04:00

31 KiB
Raw Blame History

Executive summary

The PipecatVoice work produced two useful technical outcomes: a source-backed NO-GO for putting Pipecat SmallWebRTC directly into the current Tactility external ELF, and a simpler protocol-v1 LAN WebSocket adapter/client architecture with passing deterministic tests and successful ESP32-S3 builds. However, the final hardware/runtime gate is still open: the strongest recorded device evidence is an installed app showing RECONNECTING / Gateway unavailable, with no accepted board WebSocket session, no board-originated PCM/VAD proof, no downstream device-playback proof, and no full STT → Hermes → TTS proof.

Most observed board transitions were normal Hermes Kanban behavior. The orchestration failure was that the work graph, task text, evidence gates, and action permissions were not kept aligned after the architecture pivot. Repeatedly unblocking the same permission-gated task correctly triggered Hermes's block-loop breaker and moved it to triage; comments and dispatcher nudges could not make a triage or dependency-gated task runnable. Tomorrow's work should use one canonical, dependency-correct chain and separate credential-independent transport/audio proof from credential-dependent STT/Hermes/TTS proof.

No voice-app implementation changes were made during this postmortem. No firmware, adapter, runtime service, configuration, device, or Kanban implementation was changed, built, flashed, installed, started, stopped, restarted, dispatched, unblocked, or archived. The only file written was this report.

1. Scope, method, and evidence labels

This report is read-only research based on:

Labels used below:

  • Verified fact — directly present in the cited source, task history, log, or inspected repository state.
  • Inference — the most likely explanation produced by combining verified facts; not direct runtime proof.
  • Recommendation — proposed future operating practice or task design.

2. Hermes Kanban semantics that matter here

2.1 Canonical lifecycle and dependencies

Verified fact: A task status is one of triage, todo, ready, running, blocked, done, or archived. There is no separate core review status. Review is a convention: a code worker comments structured evidence and blocks with a review-required: reason.

Verified fact: A parent→child link is a hard dependency. A child is ready only when every parent is exactly done; otherwise it is todo. archived is not equivalent to done. Linking an open or archived parent to a ready child demotes the child to todo.

Verified fact: unblock moves a task to:

  • ready when all parents are done; or
  • todo when any parent is still open/non-done.

It never moves a task to triage.

Verified fact: triage is a parking/specification/orchestration state, not a dispatchable worker queue. With auto-decompose enabled, the decomposer may process it; ordinary worker dispatch does not treat it as ready.

2.2 Blocking, recurrence, and triage escalation

Verified fact: Typed block kinds have different meanings:

  • dependency: routes to todo and waits for parent completion; no human unblock should be needed.
  • needs_input: human decision or answer is required.
  • capability: a hard access/credential/tool wall.
  • transient: a retryable temporary failure.

Verified fact: The local kernel has BLOCK_RECURRENCE_LIMIT = 2. If a task is blocked, unblocked, and then re-blocked for the same true-block reason twice, Hermes emits block_loop_detected and routes the task to triage. The recurrence counter intentionally survives unblocks and resets only on successful completion.

Consequence: Repeatedly adding “UNBLOCK” comments or nudging the dispatcher does not restore a triage task. The cause must be resolved, then a human/orchestrator must deliberately re-specify/promote/recreate the work in a runnable state.

2.3 Dispatcher and worker execution

Verified fact: The configured dispatcher runs inside the default gateway every 60 seconds. Current relevant settings are:

  • dispatch_in_gateway: true
  • dispatch_interval_seconds: 60
  • failure_limit: 2
  • auto_decompose: true
  • dispatch_stale_timeout_seconds: 14400 (4 hours)
  • no per-profile in-progress cap

Verified fact: The dispatcher atomically claims ready tasks and spawns the named Hermes profile as a full OS process with task, board, run, workspace, profile, and claim identifiers in environment variables. Every claim creates a separate task_runs row.

Verified fact: Comments are durable context for the next worker run. They are not executable commands, do not interrupt or redirect a running worker, and do not themselves change task status.

Verified fact: A dispatcher nudge only runs a dispatch tick. It does not unblock a blocked task, promote a triage task, satisfy an unfinished parent, approve a guarded command, or change a worker's current tool-approval state.

2.4 Retries, watchdogs, and what they cannot do

Verified fact: Hermes handles distinct failure classes:

  • dead worker PID → crash detection and retry/circuit-breaker accounting;
  • max runtime exceeded → terminate and requeue, counting as failure;
  • stale long-running worker with no recent heartbeat/activity → terminate and requeue without a failure-counter tick;
  • worker exits without kanban_complete or kanban_block → protocol-violation retry, then bounded auto-block;
  • repeated spawn/crash/timeout failures → circuit breaker and gave_up/blocked.

Verified fact: The current stale timeout is four hours, and workers should heartbeat at least hourly. A heartbeat only proves worker liveness; it does not prove acceptance criteria, runtime health, or progress on an external device.

Verified fact: The comments authored as watchdog in the PipecatVoice cards are coordination messages from a watchdog actor. They are not evidence that the core dispatcher executed the requested hardware steps. Core stale/crash watchdog behavior manages worker process lifecycle only.

Verified fact: A live worker blocked on a separate tool security/approval gate cannot be made to execute that action by a Kanban comment, heartbeat, or dispatcher nudge. The external action must be approved through the controlling execution surface or performed through an explicitly approved alternative.

2.5 Review and evidence handoff

Verified fact: Parent handoffs include only the parent's most recent completed run summary/metadata. A blocked review-required run preserves its reason and comments, but does not act like a completed dependency.

Verified fact: The recommended code-review convention is:

  1. write a structured evidence comment;
  2. block with review-required:;
  3. reviewer inspects artifacts and either approves/finishes or comments requested changes and unblocks.

Recommendation: Do not use review-required as a catch-all for missing runtime prerequisites. Record implementation review and runtime capability as separate cards/gates; otherwise the same card repeatedly re-blocks for different unresolved causes and eventually enters triage.

3. Reconstructed PipecatVoice history and task graph

3.1 Initial goal and SmallWebRTC design

Verified fact: Root task t_139d9fb9 began as a goal-mode Tech Lead task to replace an 831-line copied picker/PTT/transcript UI with a minimal native auto-start client connected to the working Pipecat 1.7 SmallWebRTC gateway.

Verified fact: The Tech Lead intake correctly established:

  • the copied UI and bespoke raw-WS assumptions were rejected;
  • the board was an ESP32-S3 on /dev/cu.usbmodem31201;
  • the live Pipecat service was on port 7860;
  • SmallWebRTC used /start, offer/answer, ICE, DTLS-SRTP/RTP, and normally Opus;
  • Tactility external-ELF compatibility had to be proven before implementation.

Verified fact: The first child chain deadlocked. Original children t_890febc7 and t_39d4fb79 were dependent on the still-open Tech Lead root, while the Tech Lead root blocked waiting for child implementation evidence. Replacement runnable cards t_13e9409d and t_2cb9b047 were then created to break that circular lifecycle.

3.2 Feasibility spike result

Verified fact: Replacement spike t_13e9409d produced a durable report and a source-backed decision:

  • Pipecat's official ESP32 client exists and built as a full ESP-IDF firmware target.
  • The build used libpeer, ICE, DTLS-SRTP, RTP, Opus, Wi-Fi, HTTP/netif, mbedTLS, and board/BSP dependencies.
  • The resulting firmware nearly filled its 1.5 MiB partition and had a large BSS footprint.
  • The current Tactility external ELF did not export/package the required dependency set.
  • Therefore: NO-GO for the current external ELF; GO only as a separate firmware/SDK integration project.

Verified fact: No hardware deploy or flash was claimed by the spike.

Verified fact: The spike also removed a hard-coded credential from app code/config. Historical worker log output nevertheless retained the removed value in a rendered diff. This report intentionally does not reproduce it.

Security recommendation: Treat that historical credential as exposed to durable local task logs: rotate/revoke it if still valid, restrict access to the worker logs, and add secret redaction before diff/log persistence. Do not paste sensitive diffs into Kanban comments or metadata.

3.3 Architecture pivot to a Mac-hosted adapter

Verified fact: User comments corrected the architectural assumption: an existing device-facing route on port 8642 was separate from the SmallWebRTC service on port 7860. It was not automatically protocol-compatible with Pipecat, but it offered a simpler adapter boundary.

Verified fact: The approved pivot moved complexity to the Mac:

Tactility app
  -- protocol-v1 WS, 16 kHz mono S16LE -->
Mac LAN adapter
  -- VAD / STT / Hermes-Pipecat turn processing / TTS -->
Mac LAN adapter
  -- metadata + downstream PCM -->
Tactility app / I2S speaker

The ESP32 would own only connection state, bounded PCM capture/playback, reconnect, and minimal UI. The Mac would own credentials and protocol translation.

3.4 Adapter implementation evidence

Verified fact: Adapter task t_6983cb62 completed with:

  • a dedicated LAN-only WebSocket adapter;
  • protocol-v1 framing and limits;
  • a shared Pipecat turn-service boundary;
  • 7/7 adapter tests;
  • lint and targeted type checks passing;
  • a live bind/smoke test while Hermes stayed loopback-only.

Verified fact: The tone smoke proved handshake and upstream byte transport (ready=true, 32,000 upstream PCM bytes). It did not prove speech recognition or downstream audio; downstream frame/byte counts were zero.

Verified fact: The worker explicitly recorded that STT → Hermes → Kokoro was unproven because recognizable speech and the required Mac-side Hermes credential were unavailable in that run.

Assessment: Completing the adapter card was defensible only as an adapter implementation milestone because the handoff clearly named the missing credential-dependent gate. It was not end-to-end voice proof.

3.5 Native protocol-v1 client implementation

Verified fact: Client task t_548c79a4 replaced the copied UI with a minimal auto-start protocol-v1 client and added host-testable protocol/state helpers. Recorded verification included:

  • strict host protocol test passing;
  • ESP32-S3 app build/package passing;
  • all loader symbols resolved in the then-available verifier context;
  • adapter tests passing;
  • hardware identity rechecked.

Verified fact: Hardware proof was missing at the first block. Later, direct foreground/user intervention installed and launched the app on board 192.168.68.129 and moved the adapter to the board-reachable .112 address.

Verified fact: A subsequent run collected the decisive negative runtime evidence:

  • board run request returned ok;
  • screenshot showed RECONNECTING / Gateway unavailable; retry scheduled;
  • adapter was listening on 192.168.68.112:8642 but had no active board TCP session;
  • serial showed app/I2S lifecycle and retry-related activity only;
  • there was no upstream PCM, VAD, transcript, downstream audio, playback, or reconnect recovery proof.

Verified fact: Sanitized connection-stage logging was added and the diagnostic build passed host/build/symbol checks, but the new package was not installed because the private-network dashboard PUT remained behind the execution approval gate.

3.6 Duplicate continuation cards and final board state

Verified fact: The original Tech Lead and implementation cards were archived. Two overlapping hardware-validation continuations then existed:

  • t_f3c3aaeb — canonical hardware WS/speaker-loop proof, now triage after two repeated approval blocks.
  • t_357758e3 — another runtime-validation continuation, now blocked on the same install/run approval.

Verified fact: t_f3c3aaeb behaved exactly as designed: run 16 blocked for approval, was unblocked, run 18 hit the same approval gate, and Hermes emitted block_loop_detected, moving the task to triage.

Verified fact: t_357758e3 says in its body that it was deliberately parentless to avoid archived-parent deadlock. Its event history then shows it was linked to archived root t_139d9fb9, and its current parent list includes that archived task.

Inference: t_357758e3 could run once because it had already been claimed when the link was added. On a later unblock, that archived/non-done parent would cause it to land in todo, not ready, recreating the dependency deadlock its body intended to avoid.

Verified fact: t_5b0e7de4, the Tech Lead evidence-review card, remains todo behind the unfinished hardware-validation dependency.

4. What went wrong versus normal Kanban behavior

4.1 Normal Kanban behavior — not bugs

  1. Children stayed todo behind an unfinished parent. This is correct dependency enforcement.
  2. Archived parents did not satisfy dependencies. Correct: only done satisfies a parent edge.
  3. Blocked tasks did not run until unblocked. Correct human-in-the-loop behavior.
  4. A second same-cause block moved the task to triage. Correct block-loop protection.
  5. Dispatcher nudges did nothing for blocked/triage/todo cards. Correct: dispatch only claims ready tasks.
  6. Comments did not alter a running worker's approval state. Correct: comments are durable next-run context, not execution control.
  7. The watchdog did not perform acceptance tests. Correct: worker watchdogs supervise lifecycle/liveness, not hardware truth.
  8. A worker refused to claim install/run success after pending_approval. Correct and safer than fabricating device evidence.
  9. Compile/build/symbol evidence did not prove device/runtime success. Correct evidence separation by the workers, even though the task graph later blurred the gates.

4.2 Orchestration mistakes

  1. Circular/inverted root ownership. The root Tech Lead task was both an upstream parent and a downstream reviewer waiting on its own children. The first child chain therefore could not start without replacement cards.
  2. Architecture changed faster than task bodies. SmallWebRTC bodies, protocol-v1 comments, .102 and .112 endpoints, and credential assumptions coexisted. Later comments superseded earlier bodies, but every worker still received the stale material.
  3. Archived tasks remained in the dependency design. Archiving did not complete the chain. A later “parentless” continuation was linked back to an archived root, reintroducing a hidden todo deadlock.
  4. Duplicate canonical hardware cards. t_f3c3aaeb and t_357758e3 cover substantially the same validation. This split attention and made status interpretation harder.
  5. Permission-gated actions were assigned to unattended workers without pre-clearing the gate. The exact private-LAN PUT/POST was repeatedly required but repeatedly returned pending_approval. Re-spawning could not change that execution policy.
  6. Repeated unblock without removing the cause. The same approval-dependent card was unblocked twice, correctly tripping the loop breaker. Tech Lead and watchdog comments then kept asking for dispatch even though the task was in triage.
  7. One card bundled too many proof domains. Endpoint diagnosis, package install, WebSocket handshake, mic transport, VAD, speaker playback, reconnect, STT, Hermes credentials, and TTS all sat in one acceptance gate. One credential/approval issue prevented clean progress reporting for independent layers.
  8. Review-required and capability blocking were conflated. Code review, hardware approval, and missing runtime credentials should have been separate cards or explicit sequential gates.
  9. Foreground intervention was not normalized back into the board. The user successfully installed/launched the app and corrected the reachable adapter endpoint, but the active graph still contained old endpoint text and duplicate approval-gated cards. Manual progress was recorded mostly as comments rather than a single revised canonical body and dependency graph.
  10. Evidence was requested repeatedly rather than made structurally prerequisite. Watchdog comments repeated screenshot/serial/adapter requirements, but no executable state transition or pre-approved worker environment accompanied them.
  11. A tool/skill mismatch appeared in logs. A worker log reported Unknown toolsets: esp32_voice; the repository-required tactility-app-development skill was also unavailable to this Tech Lead profile during this report. Task-specific tools/skills should be verified before dispatch.
  12. Sensitive diff material reached durable logs. Removing a credential from source was correct, but logging the deletion diff retained the old secret in the audit trail.

4.3 The central orchestration failure

Inference: The fundamental mistake was treating Kanban as if repeated comments, unblocks, dispatcher nudges, and watchdog reminders could substitute for a corrected state graph and an approved execution channel. Kanban faithfully persisted and enforced the states it was given. The graph and permissions—not the dispatcher—were inconsistent with the desired next action.

5. Corrected operating model

5.1 One source of truth per layer

Recommendation: Maintain one current design note and one canonical card per active gate:

  • Architecture decision record: Mac-hosted protocol-v1 adapter; no ESP32 WebRTC in this effort.
  • Canonical endpoint: selected and verified at task start; source, README, persisted config, adapter bind, and task body must agree.
  • Canonical hardware-validation card: exactly one.
  • Canonical final-review card: depends on completed proof cards, not an archived orchestration root.

When scope changes, edit the task body or create a replacement and archive the stale task only after removing/rebuilding dependency edges. Do not rely solely on “supersedes above” comments.

5.2 Separate implementation, runtime, and credential gates

Recommendation: Use these evidence classes:

Gate Must prove Must not claim
A. Static/host protocol unit tests, lint/type checks, build, symbol resolution device connectivity or audio
B. Device transport app runs, 101 upgrade/accepted session, connected screenshot, serial lifecycle, adapter session intelligible speech, Hermes, or TTS
C. Upstream audio board-originated PCM/frame counters and VAD turn boundaries STT correctness
D. Downstream audio deterministic adapter-generated response PCM received and written to I2S TTS correctness
E. Recovery adapter interruption causes RECONNECTING and automatic return to STREAMING conversational success
F. Credential-dependent pipeline recognizable speech → STT result → Hermes response → TTS frames → device playback complete until all service credentials are available and real logs exist

Gates B–E should be achievable without Hermes/STT/TTS credentials. Gate F should be a separate card that can block honestly on missing Mac-side credentials without invalidating transport/audio proof.

5.3 Permissions are prerequisites, not retry conditions

Recommendation: Before dispatching a hardware worker:

  1. Confirm the exact board IP, app ID, serial port, adapter endpoint, and allowed actions.
  2. Pre-approve the exact private-LAN operations through the execution system that will enforce approval.
  3. Confirm the worker can perform GET screenshot, PUT install, POST run, serial read, and adapter-log read.
  4. Only then move the card to ready.

If the tool still reports pending_approval, block once with a precise action. Do not repeatedly unblock until the approval controller—not merely a comment—shows the action is executable.

5.4 Evidence-first lifecycle

Recommendation: Each proof card should end with a structured comment containing:

  • exact source revision/diff scope;
  • exact command/action and actual result;
  • board identity and serial port;
  • endpoint and persisted-config source;
  • screenshot/log artifact paths or task attachments;
  • counters/state transitions;
  • what remains unproved;
  • explicit pass/fail for that card's gate.

A reviewer should inspect attachments and source before moving the next card. “Adapter is live,” “board is reachable,” and “run returned ok” are prerequisites, not proof of streaming.

The following is a proposed graph, not a set of tasks created by this report.

Task 0 — Human/Tech Lead board reconciliation

Owner: Tech Lead with human board-control access.

Actions:

  • Choose one canonical hardware-validation card.
  • Remove every dependency on archived t_139d9fb9.
  • Archive or close the duplicate continuation only after preserving unique evidence.
  • Replace stale body text so .102, SmallWebRTC, and obsolete credential assumptions are not in the canonical card.
  • Verify assignee profile and required skill/tool availability.
  • Verify the exact hardware PUT/POST actions are approved in the execution control plane.

Exit gate: one ready card, no archived parents, no duplicate runtime card, no unresolved action approval.

Task 1 — Endpoint and persisted-config diagnosis

Owner: Coder.

Scope:

  • Read current source default, README, adapter bind, and device user-data config.
  • Determine whether persisted config.json overrides .112 with stale .102.
  • Install the already-built sanitized diagnostic image only if needed and approved.
  • Capture serial stage logs and adapter access logs.

Exit gate:

  • exact endpoint source identified;
  • either WebSocket upgrade accepted or a concrete failing stage proven;
  • screenshot and serial/adapter artifacts attached;
  • no transport redesign.

Task 2 — Device transport and upstream mic proof

Parent: Task 1 done.

Scope:

  • Reach CONNECTED/STREAMING.
  • Prove accepted protocol-v1 session.
  • Prove board-originated PCM byte/frame counters and VAD completion using non-sensitive audio.

Exit gate:

  • connected/streaming screenshot;
  • serial connection lifecycle;
  • adapter accepted-session plus upstream counters;
  • no dependency on Hermes credential or STT success.

Task 3 — Downstream speaker-path proof

Parent: Task 2 done.

Scope:

  • Use an approved deterministic, non-secret response PCM fixture at the adapter boundary.
  • Prove metadata, downstream bytes/frames, device receipt, and I2S write/playback.

Exit gate:

  • adapter downstream counters;
  • client serial metadata/I2S evidence;
  • human-observed or instrumented playback evidence;
  • no TTS credential required.

Task 4 — Reconnect proof

Parent: Tasks 2 and 3 done.

Scope:

  • Perform one approved adapter interruption.
  • Prove STREAMING → RECONNECTING → STREAMING without user input.

Exit gate: timestamp-correlated screenshot/serial/adapter evidence for all three states and bounded retry behavior.

Task 5 — Credential-dependent conversational proof

Parents: Tasks 2 and 3 done. This may run after Task 4 or in parallel if safe.

Scope:

  • Confirm required Mac-side credentials are present without reading or printing values.
  • Use a short approved spoken phrase or fixture.
  • Prove STT output, Hermes/Pipecat turn completion, TTS frame production, downstream delivery, and device playback.

Exit gate: sanitized service-stage evidence and byte/frame counters. If credentials are absent, block this card only; Tasks 2–4 remain valid.

Task 6 — Tech Lead evidence review

Parents: Tasks 1–5 done, or Tasks 1–4 done with Task 5 explicitly blocked as a named credential gate if the release scope permits transport-only acceptance.

Review:

  • inspect diffs and logs directly;
  • confirm source/docs/persisted config agree;
  • verify no credentials/raw audio/transcripts were persisted;
  • confirm tests/build/symbol checks;
  • confirm device/transport/upstream/downstream/reconnect evidence;
  • state exactly whether conversational proof passed or remains credential-blocked.

Exit gate: approved structured handoff, residual risks, and a deliberate decision about whether credential-dependent proof is required for release.

7. Morning checklist

Tech Lead

  • Open the live task graph; do not rely on yesterday's comments alone.
  • Select one canonical runtime card and remove archived-parent edges.
  • Resolve triage deliberately; a dispatcher nudge is not enough.
  • Update the canonical body to protocol-v1 WS and .112; remove stale WebRTC/.102 instructions.
  • Confirm exact approval for dashboard PUT/POST and serial/log access in the actual worker execution surface.
  • Verify coder exists and required task skills/toolsets are installed.
  • Split credential-independent and credential-dependent proof.
  • Require artifact-backed evidence, not “live/reachable/ok” summaries.

Coder

  • Call kanban_show and follow only the revised canonical body.
  • Inspect git status/diff and preserve unrelated changes.
  • Reconfirm board identity, app ID, serial port, adapter bind, source default, README, and persisted config.
  • Run static tests/build/symbol checks once; do not repeat them as a substitute for runtime evidence.
  • Use screenshot, serial, and adapter logs together to identify the exact WebSocket stage.
  • Prove transport, upstream PCM/VAD, downstream PCM/I2S, and reconnect as separate gates.
  • Do not expose credentials, raw audio, or transcript content in durable logs.
  • Block once on a real approval/capability gate; do not self-loop.

Orchestrator / board operator

  • Ground every assignee in hermes profile list.
  • Ensure only done parents gate downstream tasks.
  • Never use an archived orchestration root as a parent.
  • Do not create duplicate canonical cards.
  • Treat comments as context, not state transitions.
  • Do not repeatedly unblock the same unresolved reason.
  • Understand that triage, todo, blocked, and ready require different corrective actions.
  • Use one dispatcher owner; do not start a competing standalone daemon.
  • Keep watchdog messages concise and actionable; they cannot satisfy evidence or approvals.

8. Current verified state and remaining risks

Verified repository state at report time

  • Branch main, HEAD 6e83272c8e6c09af1c0b093e56ccd7e1dfdb5fa8, one commit ahead of origin/main.
  • PipecatVoice currently has four modified tracked files and five untracked app-related paths.
  • git diff --check -- Apps/PipecatVoice returned no errors.
  • No build or test was run during this report because the task was explicitly read-only.

What is proven

  • Official Pipecat ESP32 SmallWebRTC client exists and builds as full firmware.
  • Current Tactility external ELF is not proven capable of hosting that dependency set and has a documented NO-GO decision.
  • Protocol-v1 LAN adapter implementation has deterministic test/lint/type evidence.
  • Host-generated tone reached the adapter and exercised upstream framing/VAD failure mapping.
  • Minimal protocol-v1 client has host-test/build/symbol evidence from prior runs.
  • App package was installed/launched on the personal board during direct foreground intervention.
  • The app subsequently displayed RECONNECTING while the adapter listener had no board TCP session.

What is not proven

  • Accepted ESP32 WebSocket upgrade/session at .112:8642.
  • Board-originated upstream PCM reaching adapter VAD.
  • Downstream PCM reaching and playing through board I2S.
  • Automatic reconnect recovery.
  • Recognizable speech transcription from the board mic.
  • Hermes/Pipecat response generation for the board session.
  • Kokoro/TTS output delivered to and played by the device.

Residual risks

  1. Persisted user-data config may still override the compiled .112 default with stale .102; this is an inference until inspected on the device.
  2. README/config documentation and source endpoint remain inconsistent in inspected evidence.
  3. The active continuation graph contains duplicate cards and an archived parent edge.
  4. The exact install/run security approval remains unresolved in worker execution.
  5. Credential-dependent services remain unproven and must not be conflated with transport proof.
  6. Historical worker logs contain a removed sensitive value; rotation/redaction review is warranted.
  7. The documented local SDK/firmware verifier paths have drifted across runs; tomorrow's card must record the actual environment it uses.

9. Bottom line

Hermes Kanban did not lose the work or behave unpredictably. It preserved enough task/run/comment evidence to reconstruct the failure accurately. The dispatcher, dependency engine, block-loop breaker, and approval-aware workers mostly behaved as designed. The failure was operational: the architecture pivot was not followed by a clean graph rewrite, stale and duplicate cards remained active, permission-gated hardware actions were treated as retryable work, and independent evidence layers were bundled into one terminal gate.

The shortest safe path tomorrow is not another broad “finish PipecatVoice” card. It is: reconcile the board, pre-clear the exact device actions, diagnose the endpoint/persisted config, then prove transport, upstream audio, downstream audio, reconnect, and credential-dependent conversation in separate evidence-gated steps.