Skip to content

Latest commit

 

History

History
187 lines (148 loc) · 9.44 KB

File metadata and controls

187 lines (148 loc) · 9.44 KB

Product experience

This document owns code-chan's detailed product behavior and user experience.

Side-scrolling agent presentation

The 320×240 activity view is an original retro side-scrolling scene with a heavy tracked-mecha hero. It does not reproduce a third-party game or film character.

The presentation uses five independent resource families:

  1. The hero provides idle, move, attack, hit, attention, completion, and sleep motion. Attack and hit effects remain separate from hero pixels.
  2. Escort drones summarize active subagents without filling the screen.
  3. A floating decision item represents one explicit permission request and distinguishes pending, approved, and rejected outcomes.
  4. The expedition background alternates the terminal and middle near layers while sharing one repeating far layer.
  5. Arrival is an independent effect composed without changing the hero or destination art.

One tracked file, the scene manifest, decides every exact word on screen, where each thing sits, which control is where, which artwork plays, and what is drawn in front of what. Nothing in the firmware code overrides it. Firmware validates and loads the generated 16-color indexed LittleFS package and renders it through a fixed 24 Hz compositor.

Drone count encoding

Agent count fills three drone slots, then upgrades them in the same order:

Active subagents Drone tiers, left to right
0 none
1, 2, 3 1; 1,1; 1,1,1
4, 5, 6 2,1,1; 2,2,1; 2,2,2
7, 8, 9 or more 3,2,2; 3,3,2; 3,3,3

Counts above nine saturate visually at three tier-3 drones. The display is a calm activity summary, not an unbounded exact counter.

Foreground task ownership

The device shows one task at a time, not a dashboard of everything open. Start the bridge for Codex or for Claude Code and the screen says that app is ready. The first prompt sent while it is ready takes the device, and the screen changes to working before the hook returns — so the change is visible by the time you look up.

While the task runs the caption reads WORKING. On Claude Code's CLI, where a status line can report it, the caption shows how much of your usage is left instead — context, five hours, seven days. That read-out only changes the text. It does not move the character, add or remove drones, or make a sound, and it never appears when no task is running.

One task owns the device

A prompt from a different session is not queued and not merged. It runs normally in its own coding app and leaves the device alone; it also cannot answer a permission request on the screen. A further prompt from the session that already owns the device joins the same task instead of starting a second one, which includes the prompt Claude sends itself to deliver a finished background result.

Only the session that owns the device can change what it shows. When the app reports that its answer has ended, that ends the tool, attention, and permission display for it.

Why a finished response is not always a finished task

An agent's response can stop while work it started is still running — a background subagent, for example. Showing "done" then would be a lie, so the device keeps the task open. What it will not do is keep the task open forever, which means every reason to stay open has to name the event that ends it:

Still waiting on Ended by Who can end it
A subagent that is still running the subagent finishing the app, on its own
A subagent whose result never arrived the missing report arriving the app, on its own
A finished result nobody has collected the next prompt a person

Anything that no event can end is not a reason to wait at all, which is why an app's own list of queued background work no longer holds the device.

While the device is waiting it says WAITING, and it looks like waiting: the character rests, the servos hold still, and the screen is allowed to sleep on its own, because nothing is computing. Whether it also keeps the device depends on the table above. If the app will finish the work by itself, the device stays with that task so the completion lands on the task that earned it, and another session's prompt is turned away until then. If only a person can finish it — by prompting again — the screen keeps showing WAITING but the device is free, and the next prompt from any session takes it.

A subagent that starts after the response stopped is accepted as that task's own work. Background work legitimately spawns children late, and treating that as a contradiction is what used to wake a correctly sleeping device into an error.

Finishing

A pause waiting for a background result is not shown as completion, and a subagent finishing does not play the parent's completion effect. Claude reopening its own response continues the same task rather than starting a new one. The completion effect and sound play once, after the app says its answer ended and nothing from the table above is left, and then the screen returns to ready. A finished task cannot be resumed; a new prompt takes the device immediately. Notifications finish nothing and erase nothing. Ending the session clears it.

No clocks

No timer decides that the work finished, and no timer decides that it did not. Freeing the device while a person still owes a prompt is not a claim that the work finished — nothing is played and the task is still shown — so the device stops turning into furniture without anything being guessed from how much time has passed.

One case stays outside this. If a session dies while its response is still running, nothing can ever arrive to release the device, and the fix is to restart the bridge. That is accepted as a limit rather than patched with a timeout, because a timeout would guess exactly what this product refuses to guess.

Permission experience

Touching the floating item on screen, or bumping into it, never approves anything. The only thing that answers a request is pressing the labeled REJECT or APPROVE control, and only while five things still match: the waiting hook, the session that owns the device, its task, the current connection, and that exact request's ID. Miss any one and the press does nothing.

A session that does not own the device keeps its coding app's normal permission prompt. A timeout, an unplugged cable, a stopped bridge, malformed input, or a late answer to an old request all return nothing at all. Touching Stack-chan's body is only ever character interaction and never authorizes an operation.

This experience depends on the coding app delivering a permission hook, which is outside code-chan's control. Whether a request is raised at all follows the session's permission mode and its remembered allowances, so a session that asks nothing shows nothing on the device and is answered in the terminal as usual. That is a degradation to the app's own flow, never a silent approval. VERIFICATION.md owns the hardware observation of this path.

Connection, sleep, and power

Host connection, agent state, expression lifecycle, USB power, and board shutdown are separate conditions.

Before first ordinary use, the device presents a local body-calibration screen when it has no valid code-chan home record. The operator centers the head with the screen vertical and confirms that pose while the motors are still switched off. Pressing a second control runs a short right, center, left, center movement check. The new center is saved only if the motors actually report back from both directions. The bridge and character scene do not start during calibration; successful verified storage and output disable lead to an explicit restart.

Once the bridge and the device agree they are connected, the screen shows either "ready" or the running task, on battery or on USB alike. Before they agree, it shows what is missing — start the bridge, or connect USB — and hides every control you could press. A running task, or one waiting for your permission, keeps the screen awake.

When nothing is running, either inactivity or a short press of the side button can put the device to sleep. The firmware parks the head and switches the motors off first, then shows the sleeping character and asks the panel to switch off. The touchscreen, a short side-button press, the bridge connecting, or new work arriving can wake it. Touching Stack-chan's body cannot. The device counts itself awake only when the panel and the motors actually report back — never because enough time has passed.

A long side-button hold requests board shutdown, not sleep. The device blocks new application input, reports stopping to the selected host, and requests expression quiescence. Matching quiescence is the graceful path. A child fault or deadline preserves the first error and enters the same exactly-once PMIC fail-safe tail. An accepted PMIC request means only that firmware is awaiting power removal; a rejected request is uncertain. USB-powered and battery-powered physical results are separate hardware-acceptance cases.

Current implementation boundary

The tracked art covers the hero, three drone tiers, decision states, arrival, and layered background loops. The tracked host configurations support one selected Codex or Claude bridge at a time. The generated contracts, host checks, native firmware checks, scene checks, and CoreS3 build establish the software boundaries described here. Physical acceptance of the current integrated source is recorded separately in VERIFICATION.md.