A21 is a new StackChan/CoreS3 desktop AI workmate project. It is intentionally separate from X21 and V21. V21 is only a professional knowledge adapter target; A21 owns the embodied voice, device, network, provider, observability, and firmware discipline.
The current foundation is Go-first:
cmd/a21: A21 CLI and Gateway entrypointinternal/gateway: mock/realtime Gateway, simulator, metrics, device registry, V21 professional routinginternal/providers: provider-neutral voice and realtime adapter boundariesinternal/firmwarecheck: firmware manifest, package, artifact, upload, device identity, and flash-plan guardsfirmware/stackchan: M5Stack CoreS3/StackChan firmware lanedocs/engineering: current architecture, network, latency, observability, protocol, firmware, and phase docs
- Do not introduce new X21 names into A21 runtime code.
- Do not reuse V21 internals; call V21 only through the A21 adapter contract.
- Do not store provider API keys in firmware.
- Do not run raw PlatformIO upload. A21 blocks it by design.
- Keep firmware packages A21-named, commit-bound, manifest-backed, and dry-run checked before any future physical flash path exists.
- Keep localhost/LAN/StackChan traffic out of ambient proxies.
make verify
make namespace-audit
make firmware-tools
make firmware-test
make release-checkmake namespace-audit rejects tracked file paths that introduce X21/V21 runtime identity outside the explicit V21 adapter/docs boundary.
make firmware-tools creates the repository-local .a21-tools/ PlatformIO environment pinned to platformio==6.1.19.
make firmware-current-artifact-check validates the newest packaged firmware artifact for the current git commit through the release index and per-artifact manifest.
make latency-bench writes an ignored reports/a21-latency-bench-*.json evidence report for mock Gateway and audio WebSocket timing. The report includes current commit, network fingerprint, and redacted proxy-policy metadata so home, Shanghai office, LAN, and proxy runs can be compared without leaking proxy URLs.
A21_LAN_TARGET=a21-gateway=127.0.0.1:21080 A21_LAN_SAMPLES=5 make lan-probe writes an ignored reports/a21-lan-probe-*.json direct TCP reachability and jitter report. Use it in Shanghai for Gateway, StackChan-adjacent LAN endpoints, and the A21 V21 adapter boundary on 21121. It rejects legacy X21/V21 internal ports, does not use proxy settings, and never stores proxy URLs or credentials.
make v21-adapter-smoke writes an ignored reports/a21-v21-adapter-smoke-*.json readiness report. A21_V21_ADAPTER_URL=<adapter-boundary> make v21-adapter-smoke-execute is the explicit query smoke; it never stores query text, answer text, evidence content, full adapter URLs, credentials, proxy URLs, or API keys.
make agent-plan and make agent-io-smoke write ignored Agent I/O plan/smoke
reports for Hermes/MiMo-style background agents. For explicit host-only Hermes
smoke, set A21_HERMES_AGENT_URL and A21_HERMES_AGENT_KEY, then run
make agent-io-smoke-execute. It never stores task text, memory text,
external-agent output, credentials, full URLs, provider env values, V21 evidence
bodies, firmware commands, or device commands.
make release-check runs Go tests, namespace audit, latency mock benchmarks, firmware tests/build, raw-upload blocker verification, firmware packaging, current-artifact validation, artifact retention planning, office handoff manifest generation, and doctor. It does not flash hardware or delete artifacts.
make gatewayThen open:
http://127.0.0.1:21080/simulator
The simulator is the current no-hardware development surface for mock turns, professional evidence rendering, audio downlink buffering, and interruption behavior.
For launch-grade product-chain validation, run the Gateway once and let each evidence command compose into the final readiness report:
make product-readiness
make server-side-readiness-bundlemake product-readiness writes an A21 readiness report that separates the mock
demo surface from true launch requirements: executed provider smoke, V21
professional evidence, physical StackChan evidence, wake-word state, and real
local ASR configuration. make server-side-readiness-bundle composes the
server-side subset without replacing physical acceptance. Host gates allow an
already-running Gateway on 21080 only when /healthz proves it is
a21-gateway; unknown processes on reserved ports still block.
For a simulator-only surface, use:
make demomake demo starts the A21 Gateway and opens the Simulator.
make firmware-build
make firmware-package
go run ./cmd/a21 firmware-artifact-check --artifact firmware/artifacts/<a21-stackchan...bin>
go run ./cmd/a21 firmware-upload-check --artifact firmware/artifacts/<a21-stackchan...bin> --commit <git-sha> --port /dev/cu.usbmodemXXXXfirmware-upload-check is a dry-run receipt. It sets flash_allowed: false. Real flashing is intentionally not implemented.
For physical-device evidence:
make firmware-device-report
A21_FIRMWARE_ARTIFACT=firmware/artifacts/<a21-stackchan...bin> \
A21_DEVICE_REPORT=reports/a21-devices-<timestamp>.json \
A21_DEVICE_ID=stackchan-001 \
make firmware-device-check/v1/devices and the simulator Device Registry panel show the latest A21 connection status, mode, and expression for each registered device. They do not store utterance text or V21 evidence bodies.
When a fresh device report and explicit serial port are available, make firmware-flash-plan writes reports/a21-firmware-flash-plan-*.json. This is the strongest current no-flash receipt and still sets flash_allowed: false.
Before taking the project into the Shanghai office, run:
make office-handoffIt writes reports/a21-office-handoff-*.json with the current release-ledger-validated firmware artifact, no-delete artifact retention summary, serial inventory, and the next physical acceptance steps. It still sets flash_allowed: false and delete_allowed: false.
At the office, after office-preflight has produced a ready report, cross-check the receipts:
A21_HANDOFF_REPORT=reports/a21-office-handoff-<timestamp>.json \
A21_OFFICE_PREFLIGHT_REPORT=reports/a21-office-preflight-<timestamp>.json \
make office-acceptanceIf a no-flash firmware-flash-plan report also exists, add A21_FIRMWARE_FLASH_PLAN=reports/a21-firmware-flash-plan-<timestamp>.json. The acceptance gate checks commit, artifact, device, and no-flash/no-delete invariants across receipts.
After the device is physically present and Gateway can see it, confirm fresh StackChan identity without claiming audio/screen/motion acceptance:
A21_OFFICE_ACCEPTANCE_REPORT=reports/a21-office-acceptance-<timestamp>.json \
A21_DEVICE_ID=stackchan-001 \
make stackchan-identity-acceptanceIt writes reports/a21-stackchan-identity-acceptance-*.json, checks the office acceptance receipt against a fresh Gateway /v1/devices capture and USB serial inventory, and still sets flash_allowed: false.
After identity is confirmed, capability acceptance requires separate physical evidence for every declared StackChan surface:
A21_STACKCHAN_IDENTITY_ACCEPTANCE_REPORT=reports/a21-stackchan-identity-acceptance-<timestamp>.json \
A21_DEVICE_ID=stackchan-001 \
make stackchan-physical-evidenceThis writes a pending evidence template. After the physical observations are recorded, run:
A21_STACKCHAN_IDENTITY_ACCEPTANCE_REPORT=reports/a21-stackchan-identity-acceptance-<timestamp>.json \
A21_STACKCHAN_PHYSICAL_EVIDENCE_REPORT=reports/a21-stackchan-physical-evidence.json \
A21_DEVICE_ID=stackchan-001 \
make stackchan-capability-acceptanceTo let A21 derive Gateway-observable evidence from /v1/devices and the latest trace, add A21_DERIVE_GATEWAY_EVIDENCE=1. This can prefill microphone, audio downlink, render-state, and last touch-source observations when the Gateway has fresh events. Servo/RGB and true audible/visible confirmation still need physical evidence.
The generated evidence report uses schema_version: a21.stackchan_physical_evidence.v1. It must include passed observations for microphone, speaker, screen, screen_touch, top_touch, servo_y, and rgb before capability acceptance can pass. The acceptance report still sets flash_allowed: false; it proves capability evidence, not flashing, OTA, latency, or full-duplex quality.