State, recovery and the first native audio contract
The architecture gained explicit state and behavior services. The most important correction was to stop treating recovered history as a new live event. Native audio then gained stable event identity without changing its accepted segmentation.
Published 2026-10-10 · Dated evidence, not a live status feed
The Eagles jersey was a controlled experiment
Two departures failed to produce PERSON_LOST. A diagnostic camera command initially encountered a busy device because the perception service already owned the camera. Stopping that service was necessary before using the diagnostic capture path.
In the empty scene, an Eagles jersey draped over a chair produced 124 person detections, with confidence around 0.89–0.93. Removing only the jersey while keeping the chair, camera and software unchanged produced zero person detections and 224 chair detections in the compared capture.
That intervention supported a scene-specific cause. Raising the person confidence threshold was a poor first fix because the false detection was already highly confident. The test resolved the observed scene failure; it did not prove that the detector could never mistake clothing for a person.
Three services, three distinct responsibilities
The perception layer reports presence transitions. The state engine interprets PERSON_CONFIRMED as ATTENTIVE with presence true, and PERSON_LOST as IDLE with presence false. The behavior layer translates changes into ACKNOWLEDGE_PRESENCE or RETURN_TO_IDLE intents.
Those behavior events were not physical actions. At this checkpoint the behavior service did not make Ash speak, move a motor or drive the website animation. Keeping the intent boundary explicit allows those consumers to be integrated and qualified later.
The state engine ignored blank or malformed input and suppressed identical state/presence transitions. It persisted a current-state snapshot and emitted ASH_STATE_CHANGED for meaningful changes.
- Perception: PERSON_CONFIRMED / PERSON_LOST
- State engine: ATTENTIVE / IDLE + presence
- Behavior service: ACKNOWLEDGE_PRESENCE / RETURN_TO_IDLE
- Future physical or conversational consumers
| Timestamp | Meaning | What it cannot establish alone |
|---|---|---|
| event_timestamp | Time recorded by the source event | When the consumer processed it. |
| state_updated_at | Time of state processing/update | Freshness of camera inference. |
| Behavior timestamp | Time the behavior record was emitted | End-to-end speech or motor latency. |
A service can be running and still know the wrong thing
The first follow-only launcher started at the end of the event log. If the person had already been confirmed, no new transition arrived and the new state engine stayed IDLE. Replaying the last event before following future records restored the known state.
That repair introduced a second distinction: a recovered event can be old. A later reboot restored an event about 138.47 seconds old. It was useful historical state, not a fresh observation of a person. A synthetic event age of 46.55 seconds likewise was not a processing-latency measurement.
SW-014 made synchronization explicit. ASH_STATE_SYNCHRONIZED represented recovery; ASH_STATE_CHANGED represented a live change. The behavior filter ignored synchronization records, preventing a recovered snapshot from automatically becoming another greeting. State snapshots were replaced atomically, and duplicate state observations could refresh metadata without creating another behavior.
Starting a journal reader at its end was not sufficient by itself: a newly emitted recovery record could still look new to the behavior consumer. The event’s meaning had to carry the distinction.
The SW-014 follower captured the complete-byte boundary of its startup snapshot, then followed from the next byte. That preserved appends between snapshot reading and follower startup and left an incomplete trailing record for the follower. Empty-history and partial-line checks passed. Large snapshots, log rotation and truncation races still required separate qualification.
on state record:
if event == ASH_STATE_SYNCHRONIZED:
update recovered context; do not greet
if event == ASH_STATE_CHANGED:
evaluate the live behavior transition
# Illustrative contract, not production sourceWhat the service tests actually proved
SW-013 exercised managed behavior start/stop, absence of orphaned processes, preserved upstream services and a three-service reboot. All three layers were enabled and active, with new physical departure/return transitions recorded and no restarts in the observed interval.
SW-014 passed its isolated filtering and live checks. The following reboot was reported good by the user, but a detailed equivalent boot-evidence set was still pending. The earlier SW-013 reboot pass cannot silently become a SW-014 reboot qualification.
SW-015 tested two minutes of normal seating, thirty seconds leaning back and fifteen seconds reaching to each side without a false loss. Departure and return remained responsive. Deliberate edge-of-frame behavior was not qualified. CFG-004 therefore describes specific service and coverage evidence, not universal perception reliability.
Observed event-to-state differences of roughly 0.249–0.276 milliseconds describe one narrow processing stage. Fresh behavior observations around 0.261–0.493 seconds describe another interval. Neither is a camera-to-speaking benchmark. An observed 2.731-second edge transition remained in the record.
Backups of selected service/source files were listed or compared at named checkpoints. They did not establish a bootable disk image or a successful disaster-recovery restore. Fresh-frame monitoring, log rotation, truncation handling and extended endurance remained open.
September 30: a spatial observer without actuator authority
The spatial observer developed alongside production presence detection. It used normalized geometry, a confidence floor of 0.50 and an area-ratio floor of 0.05 to avoid allowing tiny detections to control zone decisions. In a 371-detection replay, 364 records qualified and seven remained non-authoritative, with one zone transition.
Hysteresis used different boundaries depending on the current zone: CENTER to LEFT below 0.37, LEFT back to CENTER above 0.43, CENTER to RIGHT above 0.63, and RIGHT back to CENTER below 0.57. Equality retained the zone. The gap between entry and exit thresholds reduces boundary oscillation. These normalized boundaries were tested in replay; they did not establish physical room calibration.
Live evidence then exposed multiple detections competing within a frame. Phase 4D chose the largest qualified target by area, used confidence as a tie-break, retained secondary targets and updated its tracker once per frame. The 99,669-frame replay produced eight zone transitions, two in each direction between CENTER and LEFT/RIGHT. A surrounding-frame audit supported the remaining changes.
A raw-output tap was inserted ahead of the unchanged production gate. That changed the launcher and required one intentional perception restart. A pass-through check and a terminated shadow-consumer check supported isolation. The later handoff from the older observer to Phase 4D did not restart production perception.
Phase 4D became the sole live spatial observer and produced growing telemetry while production stayed healthy. Its authority remained ADVISORY_ONLY: no behavior or actuator commands, and no new reboot/endurance qualification.
- Camera / inference output
- Raw-output tap
- Unchanged production presence gate + separate spatial observer
- Spatial telemetry only; no actuator authority
Continuity scoring was an experiment, not identity recognition
Phase 5 stayed offline against frozen replay data while Phase 4D stayed live. The experiments introduced ACQUIRE, TRACK, LOST and REACQUIRE states. A continuity score and a 0.75 acceptance threshold attempted to avoid switching merely because another box became larger.
The early chained replay agreed with Phase 4D on 99.835 percent of comparable frames, with 152 differences and a longest disagreement of 28 frames. That measured agreement with a selection algorithm, not whether the same physical person was tracked correctly.
An intermittent-loss weakness led to a strike-and-recovery revision: three missing or rejected observations caused reacquisition, while ten consecutive good frames cleared the accumulated strikes. A subsequent sweep tested several strike/recovery pairs. All retained a maximum disagreement of 38 frames. The 3/15 variant reached 99.168 percent agreement but spent 2,136 frames in reacquisition; no winner was promoted.
A trace supported the interpretation that continuity could preserve a coherent target while largest-area selection switched to another detection. Without physical identity ground truth, it remained an interpretation. Track-ID work was deferred.
A synthesized file and a deliberate preflash stop
Piper with the existing Lessac medium model generated a 4.725-second mono, 16-bit PCM WAV at 22,050 Hz on September 30. File synthesis passed. No speaker was connected, so the test did not establish audible playback. An enumerated amplifier device was not a substitute for an assembled speaker chain.
The reSpeaker XVF3800 four-microphone array with XIAO ESP32S3 was received and identified through its USB and factory-safe-mode DFU interfaces. Firmware and documentation were located and their hashes recorded. The initial absence of USB audio was treated in the context of the factory interface configuration, not as proof of a defective board.
Work stopped before any firmware write and the module was disconnected. USB runtime audio, capture, direction of arrival, VAD behavior and physical playback remained unqualified. This was a preserved stopping point, not a completed microphone-array installation.
Speech segmentation before conversation
The October 1 native listener used C++ with SDL capture at 16 kHz, mono float32 and a 1,024-sample callback. Whisper tiny.en ran English greedy decoding on four CPU threads; Silero 6.2 voice activity detection used two CPU threads. These were CPU paths, not language-model workloads accelerated by Hailo.
The VAD configuration used a 0.50 threshold, 250 ms minimum speech, 300 ms acoustic silence, 100 ms padding, a 20-second maximum and 0.10-second overlap. Rolling reanalysis reset detector state. A separate 1.20-second turn-silence rule allowed thinking pauses longer than the acoustic segmentation boundary.
Earlier versions exposed duplicate rolling text, merging problems and over-aggressive turn splitting. V1.5 preserved the accepted turn assembly. A 12.49-second thought closed about 1.372 seconds after its end; a 1.93-second phrase closed about 1.338 seconds after its end. A name was still recognized incorrectly, showing that a useful turn boundary did not guarantee correct words.
V1.6 changed identity, not the listening behavior
V1.6 added a fresh process UUID read from the kernel and a sequence beginning at one. The event ID combined the runtime UUID and local sequence. Capture was to fail before starting if a valid runtime identity could not be obtained. Existing log records stayed unchanged.
Five distinct IDs were observed over two launches: four in the first run and one in the second. The second launch had a new UUID and restarted its sequence at one. The Pi build and that restart check supported the identity contract without reopening the frozen V1.5 segmentation settings.
AUDIO_TRANSCRIPT_READY
runtime_id: <fresh process UUID>
event_id: <runtime_id>:<sequence>
timestamp_ms, model, duration, text
# Field sketch; identity is not delivery assurance.| Supported by the check | Not established |
|---|---|
| Distinct IDs across the observed launches | Exactly-once consumption or duplicate suppression downstream. |
| Sequence restarts inside a new runtime namespace | Power-loss durability or filesystem-full recovery. |
| V1.5 segmentation retained | A general transcription-accuracy guarantee. |
The unrun patch stays unrun
Review found that an unchecked stream write could report a saved transcript even if writing failed. A write-checking patch was proposed, but the user explicitly said the new commands had not been run. That patch remained NOT RUN: no claim of copying, compiling or testing it on the Pi belongs in this checkpoint.
The native transcript event was not yet integrated into cognition in this dated October 1 record. Later voice experiments developed a separate conversation path; they do not retroactively complete this integration. The reSpeaker microphone-array work also remained a separate hardware qualification item rather than a substitute for demonstrated capture.