Skip to content

Aliveness overhaul: restore dropped face channels, persistent temperament, per-persona character, spoken failures - #231

Merged
RobVanProd merged 5 commits into
mainfrom
agent/aliveness-tier1-tier2
Aug 13, 2026
Merged

Aliveness overhaul: restore dropped face channels, persistent temperament, per-persona character, spoken failures#231
RobVanProd merged 5 commits into
mainfrom
agent/aliveness-tier1-tier2

Conversation

@RobVanProd

Copy link
Copy Markdown
Owner

Summary

Follow-up to the 2026-08-13 full-repo aliveness audit. Tracking ledger: ALIVENESS_WORKPLAN.md (AL-01..AL-14). Every firmware change stops at done-source: nothing here claims physical qualification, and no image was flashed.

Firmware (AL-01..AL-05)

  • Restore the dropped persona face channels. FaceAnimator::samplePose rebuilt its pose from scratch and discarded the persona layer's faceX/faceY, mouth deltas, lid tilts, eye corners, and pupil scale — so breath translation, yawns, gaze lead, and sound orientation were computed every frame and never rendered. They now pass through, covered by a composed-path test.
  • One breath. The animator's private second BreathRhythm is gone; IdleLife owns the single shared rhythm for face and body.
  • No more metronomes. Deleted the ActuationEngine idle sine sway (which reintroduced exactly the motion HeadGaze replaced) and gave the idle gaze drift a re-jittered period instead of a fixed 14.3 s sine. Dead duplicate Blink.hpp/Saccade.hpp removed.
  • Every boot is different. Blink/saccade/fidget/breath/head-gaze streams seed from esp_random() at boot; native tests keep deterministic defaults.
  • Temperament survives power cycles. Emotion baseline + habituation persist to NVS on a 10-minute cadence and restore clamped to the persona bands.
  • Sleep works end to end. Sleeping now pays sleep pressure back down, making natural waking reachable (it was mathematically impossible); circadian/ambient context became a dt-scaled stored target instead of an unbounded per-message impulse.

Bridge (AL-06..AL-12)

  • Signed valence to the face (the open half of AFFECT-001): concerned voice no longer paired with a neutral face.
  • Real personas. pip/bolt were 2-line clones of spark whose prompts still answered "I am Stackchan Spark"; they are now distinct characters, glow's silently-dropped safety rules are restored, the validator rejects identity-rule mismatches and missing safety floors, and the scaffold rewrites the identity rule it copies.
  • Per-pack conversation style. The Spark-only hardcoded style palette moved into personas/<id>/style.md; all four packs now carry one.
  • Failures speak. A model failure produces a short in-character recovery line through the normal TTS path instead of silence; a configured-but-broken TTS reports tts_error instead of silently passing.
  • Mood continuity. Bounded cross-session mood/rapport in a dedicated affect_state.json (deliberately outside BridgeMemory — MEMORY_CONTRACT gates schema work behind the AUDIT-03 repairs; this state carries no user data).
  • Initiative fixed. Proactive turns get the relationship card and conversation context, and a spoken initiative line opens a bounded conversation lease so the user can answer without re-waking.
  • Beat rotation. A per-process salt stops the same question drawing the same quip across restarts.

Docs (AL-13)

Synced the seven status docs with fixes already merged on main (PRs #222/#226/#230) plus this branch's valence fix, using dated "fixed in source, physically unqualified" annotations — the genuinely open blockers (F3 vision, F1 error paths, stranded SPEAKING) now stand out.

Verification

  • pio test -e native_logic: 322/322 (was 304 baseline; new composed-path, persistence, entropy, natural-wake coverage)
  • pio run -e stackchan_release_full: builds clean
  • Bridge suite (unittest discover -s bridge): 601/601
  • Full-system soak evidence contract: pass
  • Firmware reproducible-build contract: fails on a pre-existing ZIP-traversal check that also fails on clean main (environment-level; tracked separately, not introduced here)

🤖 Generated with Claude Code

RobVanProd and others added 5 commits August 13, 2026 18:47
Tracks the audit-identified aliveness defects across firmware, bridge,
and documentation with evidence-disciplined statuses: done-source never
implies physical qualification.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…01..AL-05)

The face animator rebuilt its pose from scratch and dropped the persona
layer's faceX/faceY, mouth deltas, lid tilts, eye corners, and pupil
scale - so breath translation, yawns, gaze lead, and sound orientation
were computed every frame and never rendered. Those channels now pass
through, and the animator's private second BreathRhythm is gone:
IdleLife owns the one shared breath for face and body.

Also: remove the ActuationEngine idle sine sway that reintroduced the
metronomic motion HeadGaze replaced; give the idle gaze drift a
re-jittered period instead of a fixed 14.3 s sine; seed the blink/
saccade/fidget/breath/head-gaze streams from hardware entropy at boot
(deterministic defaults preserved for native tests); persist emotion
baseline and habituation to NVS with a 10-minute cadence; make
circadian/ambient context a dt-scaled stored target instead of an
unbounded per-message impulse; and let sleep pay back sleep pressure so
natural waking is reachable. Delete the dead duplicate Blink/Saccade
generators.

Native suite: 322/322.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Send signed valence to the firmware response_start frame instead of
  clamping to [0,1]; face and TTS now agree on concern (AFFECT-001's
  open half).
- Make pip and bolt real characters with their own traits, identity
  rule, and spoken lines; restore the two safety prompt rules Glow had
  silently dropped; validator now rejects a pack whose identity rule
  names another persona or drops the hierarchy/memory-privacy floors;
  scaffold rewrites the identity rule it copies.
- Move the Spark-only conversation style out of Python into per-pack
  personas/<id>/style.md loaded as PersonaPack.conversation_style, with
  new palettes for glow, pip, and bolt; character_harness no longer
  loads the default persona at module import.
- Speak model failures: a runner error now produces a short in-character
  recovery line through the normal TTS/downlink path instead of a bare
  silent error frame, with the real error kept in runner telemetry. A
  configured-but-broken TTS is reported as tts_error instead of
  silently passing as a successful text turn.

Bridge suites: persona_pack 20/20, character harness+red team 56/56,
lan_service 125/125.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…AL-10..AL-12)

- New bridge/affect_state.py: bounded cross-session mood baseline and
  rapport in a dedicated affect_state.json beside the memory file,
  injected as one coarse host-derived prompt line. Deliberately outside
  BridgeMemory: MEMORY_CONTRACT.md gates new memory-schema work behind
  the AUDIT-03 repairs, and this state carries no user data. Hard bands
  mirror the firmware temperament bands; rapport relaxes on idle days.
- Initiative turns now receive the relationship card and conversation
  context instead of empty tuples, and a successfully spoken proactive
  line opens a bounded conversation lease (heartbeat frame carries the
  state) so the user can answer without re-saying the wake phrase.
- Character-beat selection mixes a per-process rotation salt so the
  same question after a restart draws a different quip; within-session
  anti-repetition is unchanged and STACKCHAN_BEAT_ROTATION_SALT pins it
  for deterministic runs.

Bridge suite: 601/601.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The doc set was pinned to baseline 39b750e while three of its open P0
defects were fixed on main: demo-mode boot default (45032a4, PR #230),
the 10-second host capture lease (8e76b86, PR #226, now 13.5 s
decoupled), and dashboard stale readiness (7fd8e0a, PR #222). This
branch also fixed the response-start valence clamp (482c3ab), the
other half of AFFECT-001.

Scorecard, audit, gap analysis, task ledger, project state, bridge
handoff, and the Conversation v2 roadmap now carry dated source-fix
annotations. No Fail row was promoted, and every note states the fixes
are physically unqualified: the genuinely open blockers (F3 vision
delivering zero detections, F1 error-path qualification, stranded
SPEAKING terminals) now stand out instead of hiding among fixed rows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@RobVanProd
RobVanProd merged commit 817f855 into main Aug 13, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant