tirtc-device-builder 0.7.3 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +26 -0
- package/README.md +61 -16
- package/bin/tirtc-device-builder.js +33 -1
- package/package.json +1 -1
- package/skills/tirtc-esp32-builder/SKILL.md +150 -39
- package/skills/tirtc-esp32-builder/USAGE.md +17 -2
- package/skills/tirtc-esp32-builder/VERSION +1 -1
- package/skills/tirtc-esp32-builder/agents/openai.yaml +1 -1
- package/skills/tirtc-esp32-builder/assets/board-audio-contract.example.json +3 -0
- package/skills/tirtc-esp32-builder/assets/board-identity.example.json +16 -0
- package/skills/tirtc-esp32-builder/assets/developer-intake-prompt.md +3 -3
- package/skills/tirtc-esp32-builder/assets/hardware-ir-v2.example.json +9 -1
- package/skills/tirtc-esp32-builder/assets/lckfb-szpi-esp32s3-portable-prompt.md +5 -5
- package/skills/tirtc-esp32-builder/assets/report-template.md +10 -2
- package/skills/tirtc-esp32-builder/assets/tirtc-runtime-contract.example.json +13 -0
- package/skills/tirtc-esp32-builder/knowledge/board-registry.json +4 -0
- package/skills/tirtc-esp32-builder/references/audio-contract.md +8 -0
- package/skills/tirtc-esp32-builder/references/board-knowledge.md +72 -0
- package/skills/tirtc-esp32-builder/references/capability-rules.md +11 -1
- package/skills/tirtc-esp32-builder/references/environment.md +21 -2
- package/skills/tirtc-esp32-builder/references/firmware-delivery.md +83 -0
- package/skills/tirtc-esp32-builder/references/hardware-ir.md +12 -3
- package/skills/tirtc-esp32-builder/references/porting-risks.md +29 -1
- package/skills/tirtc-esp32-builder/references/product-controls.md +76 -0
- package/skills/tirtc-esp32-builder/references/reporting.md +8 -4
- package/skills/tirtc-esp32-builder/references/runtime-contract.md +12 -2
- package/skills/tirtc-esp32-builder/references/tirtc-platform.md +92 -0
- package/skills/tirtc-esp32-builder/references/workflow.md +42 -11
- package/skills/tirtc-esp32-builder/scripts/audio_contract.py +2 -0
- package/skills/tirtc-esp32-builder/scripts/board_registry.py +677 -0
- package/skills/tirtc-esp32-builder/scripts/firmware_identity.py +180 -0
- package/skills/tirtc-esp32-builder/scripts/hardware_ir.py +147 -8
- package/skills/tirtc-esp32-builder/scripts/runtime_contract.py +122 -1
|
@@ -83,6 +83,12 @@
|
|
|
83
83
|
"resolved": null,
|
|
84
84
|
"verification": "extracted"
|
|
85
85
|
},
|
|
86
|
+
"duplex_audio": {
|
|
87
|
+
"simultaneous_capture_playback": null,
|
|
88
|
+
"playback_reference_available": null,
|
|
89
|
+
"aec_implementation_available": null,
|
|
90
|
+
"verification": "extracted"
|
|
91
|
+
},
|
|
86
92
|
"camera_realtime": {
|
|
87
93
|
"pipeline_safe": null,
|
|
88
94
|
"verification": "extracted"
|
|
@@ -122,7 +128,9 @@
|
|
|
122
128
|
"h5_live_audio",
|
|
123
129
|
"h5_live_video",
|
|
124
130
|
"h5_talkback",
|
|
125
|
-
"ai_talk"
|
|
131
|
+
"ai_talk",
|
|
132
|
+
"device_call",
|
|
133
|
+
"wechat_voip"
|
|
126
134
|
]
|
|
127
135
|
}
|
|
128
136
|
}
|
|
@@ -7,7 +7,7 @@ $tirtc-esp32-builder
|
|
|
7
7
|
前置条件(必须由开发者在启动本次 Codex 会话前完成,不属于本提示词内的操作):
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npx --yes tirtc-device-builder@0.
|
|
10
|
+
npx --yes tirtc-device-builder@0.8.1 setup esp32 --install --force-skill
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
该命令只允许在当前用户目录安装固定版本的 Skill、managed ESP32 Device Kit、ESP-IDF 和工具链;禁止 sudo、系统级包变更和修改 shell profile。安装完成后,开发者必须关闭原 Codex 会话,再从本 clean-room 工作区启动一个新会话,然后粘贴本提示词。
|
|
@@ -15,11 +15,11 @@ npx --yes tirtc-device-builder@0.7.3 setup esp32 --install --force-skill
|
|
|
15
15
|
本轮第一步先只读运行:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
npx --yes tirtc-device-builder@0.
|
|
19
|
-
npx --yes tirtc-device-builder@0.
|
|
18
|
+
npx --yes tirtc-device-builder@0.8.1 --version
|
|
19
|
+
npx --yes tirtc-device-builder@0.8.1 setup esp32
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
必须根据命令的实际输出和本机文件确认:npm 包为 0.
|
|
22
|
+
必须根据命令的实际输出和本机文件确认:npm 包为 0.8.1、已安装 Skill 的 `VERSION` 为 0.8.1、所选 Device Kit 的 `manifest.json` 中 `kit_version` 为 1.1.1,并且 Doctor 对 `--expected-kit 1.1.1` 输出 `OVERALL: PASS`。Plugin manifest 不属于这种 npm 安装方式的运行时前置条件,不得把不可访问的 Plugin 版本当作阻塞项。如果版本不一致、Skill 是在当前会话启动后才安装,或环境检查未通过,停止并报告前置条件不成立;不要在当前会话中替换 Skill 后继续生成工程。
|
|
23
23
|
|
|
24
24
|
工作区与 clean-room 边界:
|
|
25
25
|
- 将启动 Codex 时的当前目录定义为 `WORKSPACE_ROOT`。
|
|
@@ -55,7 +55,7 @@ npx --yes tirtc-device-builder@0.7.3 setup esp32
|
|
|
55
55
|
- 每次视频调用必须发送一张完整 JPEG,禁止截断帧或裸分片。
|
|
56
56
|
- 音频 G.711 A-law、8 kHz、mono。
|
|
57
57
|
- stream:H5 上行 10、视频 11、H5 下行 14、AI 1。
|
|
58
|
-
-
|
|
58
|
+
- AI 对讲必须实现全双工和 AEC;构建阶段必须证明同时采集播放、真实播放参考与 `echo_cancellation.enabled=true`,实机结果仍只能在 L2-L7 验证后声明。
|
|
59
59
|
|
|
60
60
|
接入要求:
|
|
61
61
|
- SoftAP 配网,凭证保存 NVS。
|
|
@@ -27,6 +27,9 @@
|
|
|
27
27
|
| H5 live video | | |
|
|
28
28
|
| H5 talkback | | |
|
|
29
29
|
| AI intercom | | |
|
|
30
|
+
| Device-to-device call | | |
|
|
31
|
+
| WeChat VoIP | | |
|
|
32
|
+
| Full-duplex AEC/reference path | | |
|
|
30
33
|
|
|
31
34
|
## Semantic build gates
|
|
32
35
|
|
|
@@ -37,6 +40,8 @@
|
|
|
37
40
|
- Audio contract path/SHA-256: `{{AUDIO_CONTRACT}}`
|
|
38
41
|
- Codec clock-table result: `{{AUDIO_CLOCK_GATE}}`
|
|
39
42
|
- I2S mode/controller/slot/handoff result: `{{AUDIO_TOPOLOGY_GATE}}`
|
|
43
|
+
- Simultaneous capture/playback and AEC result: `{{AEC_GATE}}`
|
|
44
|
+
- Device-call/WeChat protocol and arbiter result: `{{BUSINESS_RUNTIME_GATE}}`
|
|
40
45
|
- Video contract path/SHA-256: `{{VIDEO_CONTRACT}}`
|
|
41
46
|
- Camera lock/PID/CPU/frame/backpressure result: `{{VIDEO_GATE}}`
|
|
42
47
|
- Final ELF I2C driver-family result: `{{I2C_ELF_GATE}}`
|
|
@@ -54,14 +59,17 @@
|
|
|
54
59
|
| L3 Online | | |
|
|
55
60
|
| L4 Media | | |
|
|
56
61
|
| L5 H5 | | |
|
|
57
|
-
| L6 AI | | |
|
|
62
|
+
| L6 AI/CALL/VOIP/AEC | | |
|
|
58
63
|
| L7 Stability | | |
|
|
59
64
|
|
|
60
65
|
## Firmware and flash record
|
|
61
66
|
|
|
67
|
+
- Delivery mode (`development flash` or `evidence bundle`): `{{DELIVERY_MODE}}`
|
|
68
|
+
- Application project/version: `{{FIRMWARE_PROJECT_VERSION}}`
|
|
62
69
|
- Serial port/chip: `{{SERIAL_TARGET}}`
|
|
63
70
|
- Project-relative firmware artifacts: `{{FIRMWARE_ARTIFACTS}}`
|
|
64
|
-
-
|
|
71
|
+
- Application-BIN SHA-256: `{{FIRMWARE_BIN_SHA256}}`
|
|
72
|
+
- Descriptor/full ELF SHA-256: `{{FIRMWARE_ELF_SHA256}}`
|
|
65
73
|
- Flash command/result: `{{FLASH_RESULT}}`
|
|
66
74
|
|
|
67
75
|
## Artifact-bound runtime evidence
|
|
@@ -6,5 +6,18 @@
|
|
|
6
6
|
"app_main": "main/app_main.c",
|
|
7
7
|
"starter_tirtc": "components/starter_tirtc/src/starter_tirtc.c",
|
|
8
8
|
"starter_runtime": "components/starter_runtime/src/starter_runtime.c"
|
|
9
|
+
},
|
|
10
|
+
"business": {
|
|
11
|
+
"features": [],
|
|
12
|
+
"protocol_revision": null,
|
|
13
|
+
"session_arbiter": {
|
|
14
|
+
"single_foreground_owner": null,
|
|
15
|
+
"pending_capacity": null,
|
|
16
|
+
"generation_guard": null,
|
|
17
|
+
"monotonic_deadlines": null,
|
|
18
|
+
"deferred_lifecycle": null,
|
|
19
|
+
"restore_h5_after_call": null
|
|
20
|
+
},
|
|
21
|
+
"implementation_assertions": []
|
|
9
22
|
}
|
|
10
23
|
}
|
|
@@ -36,6 +36,14 @@ directions are active, uses the hardware clock rate, and maps two distinct TDM
|
|
|
36
36
|
signals. Implementation assertions must still bind the contract to the paired
|
|
37
37
|
channel setup, AEC library configuration, and exact slot extraction code.
|
|
38
38
|
|
|
39
|
+
AEC is not optional when Hardware IR requests `ai_talk`, `device_call`, or
|
|
40
|
+
`wechat_voip`. For those features, `echo_cancellation.enabled=false`, missing
|
|
41
|
+
playback-reference wiring, or non-simultaneous capture/playback is a hard
|
|
42
|
+
`BLOCKED` result. Do not silently downgrade the product to push-to-talk. The
|
|
43
|
+
contract verifier exports structured `simultaneous_capture_playback` and
|
|
44
|
+
`echo_cancellation_enabled` results so the Hardware IR assessor enforces this
|
|
45
|
+
rule rather than trusting summary text.
|
|
46
|
+
|
|
39
47
|
## Mandatory gate
|
|
40
48
|
|
|
41
49
|
Run the gate before claiming an audio-capable build:
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Board knowledge and identity
|
|
2
|
+
|
|
3
|
+
Use this reference when identifying a board, reusing an existing adapter, or
|
|
4
|
+
capturing lessons after bring-up. The registry is curated, versioned input. It
|
|
5
|
+
does not train a model or mutate an installed Skill from conversation history.
|
|
6
|
+
|
|
7
|
+
## Identity boundary
|
|
8
|
+
|
|
9
|
+
An ESP32 can report its SoC target, revision, Flash/PSRAM, MAC and sometimes its
|
|
10
|
+
module. Board firmware can probe camera PIDs, codec chip IDs and other bus
|
|
11
|
+
devices. These observations identify components, not necessarily the carrier
|
|
12
|
+
board sales model, PCB marking, hardware revision, wiring, power topology or
|
|
13
|
+
acoustic path. Obtain those facts from the developer and board documents.
|
|
14
|
+
|
|
15
|
+
Create a project-local identity file, merge the developer declaration with safe
|
|
16
|
+
read-only observations, then query the registry:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
python3 <skill-dir>/scripts/board_registry.py init-identity \
|
|
20
|
+
--output <project>/board-identity.json
|
|
21
|
+
python3 <skill-dir>/scripts/board_registry.py match \
|
|
22
|
+
--identity <project>/board-identity.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Use only an `exact` result with `safe_registered_reuse=true` to install a saved
|
|
26
|
+
adapter. `probable` can supply hypotheses while missing revision or probe facts
|
|
27
|
+
are resolved. `component` can supply component-level risks and driver patterns,
|
|
28
|
+
but never GPIO, clock, DMA or adapter values. A conflict creates a new variant.
|
|
29
|
+
|
|
30
|
+
Exact matching requires vendor, model or alias, hardware revision, SoC/resource
|
|
31
|
+
compatibility, and every probe marked `required_for_exact`. Marketing names are
|
|
32
|
+
not enough because vendors may substitute sensors or codecs without renaming a
|
|
33
|
+
product.
|
|
34
|
+
|
|
35
|
+
## Knowledge scopes
|
|
36
|
+
|
|
37
|
+
- `generic`: an ESP32/TiRTC invariant. Promote only after two independent board
|
|
38
|
+
packages support it and a focused regression test enforces it.
|
|
39
|
+
- `component`: a sensor, codec, amplifier or library observation. Reuse it on a
|
|
40
|
+
different carrier only as a hypothesis until that board supplies evidence.
|
|
41
|
+
- `board`: a fact for one exact package identity. Apply it only to an exact
|
|
42
|
+
match.
|
|
43
|
+
|
|
44
|
+
Registry package status controls reuse:
|
|
45
|
+
|
|
46
|
+
- `knowledge_only`: lessons are usable, but the normal new-board intake remains
|
|
47
|
+
mandatory.
|
|
48
|
+
- `adapter_verified`: the Hardware IR, adapter, configuration and semantic
|
|
49
|
+
contracts are complete enough for the registered-board workflow.
|
|
50
|
+
- `hil_verified`: the reusable package also retains artifact-bound HIL evidence.
|
|
51
|
+
|
|
52
|
+
An older HIL result is provenance, not proof for a newly built artifact.
|
|
53
|
+
|
|
54
|
+
## Learning loop
|
|
55
|
+
|
|
56
|
+
After the final assessment, create a project-local candidate:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
python3 <skill-dir>/scripts/board_registry.py candidate \
|
|
60
|
+
--hardware-ir <project>/hardware-ir.json \
|
|
61
|
+
--output <project>/board-knowledge-candidate.json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Review the candidate before promotion. Add exact runtime probes, copy only
|
|
65
|
+
portable project-relative adapter/config/contract inputs, classify each lesson's
|
|
66
|
+
scope, attach the tested artifact SHA-256 for hardware or HIL claims, and add a
|
|
67
|
+
regression test for every generic invariant. Then commit it to a maintained
|
|
68
|
+
registry and publish a new Skill version. An installed Skill never edits itself
|
|
69
|
+
or promotes an observation automatically.
|
|
70
|
+
|
|
71
|
+
Keep credentials, MAC-derived identity, device keys, Wi-Fi secrets, tokens and
|
|
72
|
+
user media out of identity files, candidates and registries.
|
|
@@ -9,7 +9,16 @@ Run `hardware_ir.py assess --phase intake --strict` before generation. Hardware
|
|
|
9
9
|
| `h5_live_audio` | Microphone path producing G.711 A-law, 8 kHz, mono for stream 10; audio controller/channel ownership and memory budget resolved |
|
|
10
10
|
| `h5_live_video` | Camera plus the selected MJPEG, H.264, or H.265 profile for stream 11; refresh/key-frame control, realtime pipeline, and memory budget resolved |
|
|
11
11
|
| `h5_talkback` | G.711 A-law, 8 kHz downlink decode and speaker path for stream 14; audio controller/GPIO ownership and memory budget resolved |
|
|
12
|
-
| `ai_talk` | A-law 8 kHz microphone and speaker paths for AI stream 1, started only after `start_session`; audio ownership/channel mapping and memory budget resolved |
|
|
12
|
+
| `ai_talk` | A-law 8 kHz microphone and speaker paths for AI stream 1, started only after `start_session`; simultaneous capture/playback, physical reference, enabled AEC, audio ownership/channel mapping and memory budget resolved |
|
|
13
|
+
| `device_call` | Device-call protocol and arbiter contract plus simultaneous A-law capture/playback, physical reference and enabled AEC |
|
|
14
|
+
| `wechat_voip` | WeChat VoIP protocol and arbiter contract plus simultaneous A-law capture/playback, physical reference and enabled AEC |
|
|
15
|
+
|
|
16
|
+
`ai_talk`, `device_call`, and `wechat_voip` are AEC-required features. They are
|
|
17
|
+
`BLOCKED` when the board cannot capture a playback reference, cannot keep RX/TX
|
|
18
|
+
active together, or has no evidenced AEC implementation. At build time the audio
|
|
19
|
+
contract must explicitly report both simultaneous directions and enabled AEC;
|
|
20
|
+
generic full-duplex labels, a software flag without reference routing, or a
|
|
21
|
+
half-duplex fallback do not satisfy the gate.
|
|
13
22
|
|
|
14
23
|
Hardware identity, wiring, the selected media contract, and the adapter/resource design must be at least `corroborated` to become `READY_TO_PORT`. At intake, `available=true` means a pinned source path can implement the selected profile; it does not claim that the final adapter or physical media path has run. Implementation composition, final ELF policy, runtime memory margin, browser media, and stability belong to the build or HIL phases.
|
|
15
24
|
|
|
@@ -45,6 +54,7 @@ SoftAP is one Wi-Fi option, not a universal requirement. BLE, SmartConfig, facto
|
|
|
45
54
|
- Match the TiRTC precompiled SDK platform to the ESP-IDF target and its `manifest/build-contract.env` to the generated configuration.
|
|
46
55
|
- Keep H5 stream IDs and formats stable unless the user explicitly authorizes a coordinated contract change across the server and consumers.
|
|
47
56
|
- Start AI media only after the successful `start_session` response; stop and flush media before disconnecting.
|
|
57
|
+
- Route AI, device-call and WeChat VoIP through the same foreground-session arbiter and keep AEC active for the entire simultaneous capture/playback interval.
|
|
48
58
|
- Copy SDK callback payloads into bounded queues before returning. Perform decoding, playback, HTTP, and lifecycle changes outside callbacks.
|
|
49
59
|
- Use monotonic timestamps and session generation to reject stale frames and delayed callbacks.
|
|
50
60
|
- Record runtime evidence with the exact BIN/ELF SHA-256. Use `assess --phase hil --artifact-sha256 <sha>`; documentation verification alone never becomes v2 `HIL_VERIFIED`.
|
|
@@ -48,15 +48,34 @@ For an explicitly selected legacy workspace, omit `--expected-kit`; otherwise re
|
|
|
48
48
|
|
|
49
49
|
The default managed root is `<setup-root>/kits/esp32s3/<kit-version>`. The public ThingConnect workspace remains an optional legacy/development input; the doctor accepts either a Device Kit root, a repository root, or its `thing-connect/` child.
|
|
50
50
|
|
|
51
|
+
The managed Kit currently contains the ESP32-S3 H5/AI starter. When the requested
|
|
52
|
+
portfolio includes device-to-device calling or WeChat VoIP and the selected Kit
|
|
53
|
+
does not contain `device-sim-c`, `device-call.md`, `device-voip.md`, and the API
|
|
54
|
+
reference, use a full `tirtc-server-example` checkout pinned to a recorded commit
|
|
55
|
+
for the simulator and porting source. Cloning is an external write and requires
|
|
56
|
+
user authorization. Do not track a moving default branch as build evidence.
|
|
57
|
+
|
|
58
|
+
ESP32-P4 uses a separate `espressif_esp32p4` SDK archive and RISC-V toolchain.
|
|
59
|
+
The managed setup does not install that archive or generate a P4 starter. A P4
|
|
60
|
+
task therefore needs an explicit BSP/network project plus the exact P4 SDK and
|
|
61
|
+
`manifest/build-contract.env`; run Doctor with `--target esp32p4` and never accept
|
|
62
|
+
the packaged S3 archive as a compatible fallback.
|
|
63
|
+
|
|
51
64
|
SDK resolution is independent after generation: an explicit `--sdk-dir` wins, followed by `<project>/third_party/tirtc`, then the SDK packaged in the resolved Device Kit or legacy workspace. The generated project remains diagnosable after it is moved away from the Kit.
|
|
52
65
|
|
|
53
|
-
|
|
66
|
+
For the evidence-bundle mode defined in
|
|
67
|
+
[firmware-delivery.md](firmware-delivery.md), run:
|
|
54
68
|
|
|
55
69
|
```bash
|
|
56
70
|
python3 <skill-dir>/scripts/project_portability.py <generated-project> --export
|
|
57
71
|
```
|
|
58
72
|
|
|
59
|
-
|
|
73
|
+
Run it on a delivery copy and export source inputs only. CMake caches absolute
|
|
74
|
+
source, toolchain, and Python paths under `build/`; `managed_components/` may be
|
|
75
|
+
regenerated from the committed `dependencies.lock`. The bundled
|
|
76
|
+
`third_party/tirtc` SDK and its build contract must remain in the source package.
|
|
77
|
+
CMake must invoke shell gates through `bash <script>` so the build does not
|
|
78
|
+
depend on archive- or filesystem-specific executable bits.
|
|
60
79
|
|
|
61
80
|
The export check also requires Hardware IR, every requested-feature semantic
|
|
62
81
|
contract, `sdkconfig.defaults`, a referenced custom partition table, and each
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Firmware identity and delivery
|
|
2
|
+
|
|
3
|
+
Read this reference whenever the task builds, flashes, hands off, compares, or
|
|
4
|
+
retains firmware. Select the delivery mode from the user's immediate goal; do
|
|
5
|
+
not force a release bundle onto a quick device-test loop.
|
|
6
|
+
|
|
7
|
+
## Choose one mode explicitly
|
|
8
|
+
|
|
9
|
+
### Development flash
|
|
10
|
+
|
|
11
|
+
Use this mode for rapid build/flash/monitor iteration on one development
|
|
12
|
+
machine. Keep the normal ESP-IDF `build/` tree and use the ordinary command:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
idf.py -p <exact-port> flash monitor
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Do not create a new archive or make the user manually flash bootloader,
|
|
19
|
+
partition-table and application BIN files when `idf.py flash` can resolve the
|
|
20
|
+
build metadata. Before flashing, record the application version and hash of the
|
|
21
|
+
exact application BIN. A build assessment may bind to a project-relative file
|
|
22
|
+
under `build/`; that evidence remains valid only while that exact file exists.
|
|
23
|
+
|
|
24
|
+
If an experiment produces runtime evidence worth retaining, copy the unchanged
|
|
25
|
+
BIN and matching ELF into `artifacts/` before the next rebuild, record their
|
|
26
|
+
sizes and hashes, and update the report. Copying does not create a new firmware
|
|
27
|
+
identity; a rebuild does.
|
|
28
|
+
|
|
29
|
+
### Evidence bundle
|
|
30
|
+
|
|
31
|
+
Use this mode for a portable handoff, release candidate, rollback image,
|
|
32
|
+
retained HIL result, or source export. Keep project-relative copies of the exact
|
|
33
|
+
application BIN and ELF, plus bootloader and partition-table files when the
|
|
34
|
+
recipient needs manual flashing. Record byte sizes and SHA-256 values in
|
|
35
|
+
Hardware IR, run strict build assessment, then run
|
|
36
|
+
`project_portability.py --export` on the source-only delivery tree.
|
|
37
|
+
|
|
38
|
+
When promoting a development build into an evidence bundle, copy the unchanged
|
|
39
|
+
files first, then replace every retained `build/...` artifact path in Hardware
|
|
40
|
+
IR and the report with its new `artifacts/...` path. Remove transient build
|
|
41
|
+
records that are not being retained; do not merely add bundle records beside
|
|
42
|
+
stale paths. Rerun strict build assessment against the copied application-BIN
|
|
43
|
+
hash so the assessor reopens the new path. The source-only export is ready only
|
|
44
|
+
when every `build_evidence.artifacts[]` path exists outside `build/` and the
|
|
45
|
+
matching report identifies the same hashes.
|
|
46
|
+
|
|
47
|
+
Only this export workflow requires removal of the machine-bound `build/` tree.
|
|
48
|
+
Do not delete it during active iteration, and never delete a user-owned build
|
|
49
|
+
tree merely to make a report look portable.
|
|
50
|
+
|
|
51
|
+
## Make firmware self-identifying
|
|
52
|
+
|
|
53
|
+
Set an explicit, human-readable `PROJECT_VER` before `project()` in the top-level
|
|
54
|
+
ESP-IDF `CMakeLists.txt`. Keep it at 31 UTF-8 bytes or fewer so it fits the
|
|
55
|
+
`esp_app_desc_t.version` field with its terminator. Use a label that states what
|
|
56
|
+
the image is: for example `audio-repro.2`, `button-test.1`, `fix.3`, or a release
|
|
57
|
+
version. A build that deliberately preserves a known bug is a reproduction or
|
|
58
|
+
diagnostic image, not a fix.
|
|
59
|
+
|
|
60
|
+
At boot, log `project_name`, `version`, build date/time, IDF version, and the
|
|
61
|
+
full ELF SHA-256 from `esp_app_get_description()` or
|
|
62
|
+
`esp_app_get_elf_sha256()`. If the product has a console, expose the same fields
|
|
63
|
+
through `version` or `status`. This lets a tester distinguish a successful
|
|
64
|
+
flash of the wrong image from a runtime regression.
|
|
65
|
+
|
|
66
|
+
Verify the built application BIN before flash or handoff:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
python3 <skill-dir>/scripts/firmware_identity.py build/<app>.bin \
|
|
70
|
+
--elf build/<app>.elf --expect-version <expected-version>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The script reads the embedded ESP-IDF application descriptor, verifies the
|
|
74
|
+
explicit version, and confirms that the supplied ELF's full SHA-256 matches the
|
|
75
|
+
descriptor. It accepts an application BIN, not a merged whole-flash image.
|
|
76
|
+
|
|
77
|
+
## Name hashes precisely
|
|
78
|
+
|
|
79
|
+
The outer application-BIN SHA-256 and the descriptor's full ELF SHA-256 identify
|
|
80
|
+
different files. Record both with unambiguous labels; do not call either one
|
|
81
|
+
simply “firmware hash.” Bind Hardware IR artifacts and HIL observations to the
|
|
82
|
+
exact retained artifact SHA required by the assessor, and include the boot-log
|
|
83
|
+
version/full ELF hash so the physical device can be reconciled with that record.
|
|
@@ -42,16 +42,23 @@ The IR contains:
|
|
|
42
42
|
- exact board identity, module, Flash/PSRAM, ESP-IDF, TiRTC SDK and build contract;
|
|
43
43
|
- camera identity evidence plus `video_profiles[]` and `selected_video_profile`;
|
|
44
44
|
- audio input/output paths;
|
|
45
|
-
- `hardware_resources` for I2C, I2S/GPIO ownership, audio channel mapping,
|
|
45
|
+
- `hardware_resources` for I2C, I2S/GPIO ownership, audio channel mapping,
|
|
46
|
+
full-duplex/AEC capability, camera realtime policy, and memory budget;
|
|
46
47
|
- project-relative `hardware_resources.audio_semantic_contract` for every project requesting audio;
|
|
47
48
|
- project-relative `hardware_resources.video_semantic_contract` for every project requesting video;
|
|
48
|
-
- project-relative `hardware_resources.runtime_semantic_contract` for every generated H5/AI project;
|
|
49
|
+
- project-relative `hardware_resources.runtime_semantic_contract` for every generated H5/AI/call/VoIP project;
|
|
49
50
|
- `onboarding.wifi_credentials` with selectable SoftAP/BLE/SmartConfig/factory/development/custom methods;
|
|
50
51
|
- selectable ThingConnect binding methods plus stored-binding states and reset control;
|
|
51
52
|
- requested features;
|
|
52
53
|
- optional `runtime_evidence[]`, each bound to a full firmware SHA-256.
|
|
53
54
|
- `build_evidence.artifacts[]` containing each accepted BIN/ELF path, byte size, and full SHA-256.
|
|
54
55
|
|
|
56
|
+
When `ai_talk`, `device_call`, or `wechat_voip` is requested,
|
|
57
|
+
`hardware_resources.duplex_audio` must establish simultaneous capture/playback,
|
|
58
|
+
an actual playback-reference signal, and an AEC implementation. Unknown values
|
|
59
|
+
remain `NEEDS_CONFIRMATION`; a confirmed missing value is `BLOCKED`. Build/HIL
|
|
60
|
+
assessment also requires the project audio semantic gate to prove enabled AEC.
|
|
61
|
+
|
|
55
62
|
The selected Wi-Fi method must be available and corroborated, credentials must remain outside tracked source, and reprovisioning must be defined. A board without SoftAP is valid when another selected method meets those conditions.
|
|
56
63
|
|
|
57
64
|
The selected video profile controls assessment. An unselected H.264 fallback cannot make an MJPEG target pass, and missing H.264 cannot block an evidenced MJPEG target.
|
|
@@ -77,7 +84,9 @@ python3 <skill-dir>/scripts/hardware_ir.py assess hardware-ir.json \
|
|
|
77
84
|
--phase hil --artifact-sha256 <64-character-sha256> --strict
|
|
78
85
|
```
|
|
79
86
|
|
|
80
|
-
H5 features require matching L5 evidence; AI
|
|
87
|
+
H5 features require matching L5 evidence; AI, device-call and WeChat VoIP
|
|
88
|
+
require matching L6 evidence. Evidence from an older firmware remains
|
|
89
|
+
provenance but does not verify the current artifact.
|
|
81
90
|
|
|
82
91
|
## Intake quality
|
|
83
92
|
|
|
@@ -62,9 +62,37 @@ Disable Wi-Fi power saving for the realtime baseline unless the product contract
|
|
|
62
62
|
|
|
63
63
|
Confirm SDK send return semantics and callback payload lifetimes from the selected SDK version. Keep SDK callbacks bounded and copy payloads before returning.
|
|
64
64
|
|
|
65
|
+
## Repeated or duplicated downlink audio
|
|
66
|
+
|
|
67
|
+
Do not label a build as a fix merely because it adds logs or makes the symptom
|
|
68
|
+
less frequent. First produce a self-identifying reproduction build, then count
|
|
69
|
+
the same frame across four boundaries: TiRTC receive callback, accepted queue
|
|
70
|
+
item, playback dequeue, and codec/I2S write. Include mode and connection
|
|
71
|
+
generation, stream/media type, payload length, bounded queue depth/drop counters,
|
|
72
|
+
and an available transport sequence or timestamp. Sample payload hashes only as
|
|
73
|
+
diagnostic evidence; do not blindly discard equal hashes because silence or
|
|
74
|
+
legitimately repeated encoded frames may be identical.
|
|
75
|
+
|
|
76
|
+
Carry one local trace ID from the accepted callback through queue and playback,
|
|
77
|
+
and record write offset, requested bytes, returned bytes, and cumulative bytes.
|
|
78
|
+
Multiple codec/I2S writes are valid when a frame is deliberately chunked or a
|
|
79
|
+
partial write advances the offset; a local duplication exists only when the
|
|
80
|
+
same byte/sample range is committed more than once or cumulative output exceeds
|
|
81
|
+
the frame's decoded contract. Repeated callbacks with the same available
|
|
82
|
+
transport identity point upstream or into SDK delivery. Unique downlink frames
|
|
83
|
+
heard repeatedly require checking resampling, DMA/I2S replay and acoustic
|
|
84
|
+
feedback separately. On stop/reconnect, reject stale generations and drain or
|
|
85
|
+
invalidate queued audio. Verify the correction with repeated AI sessions, rapid
|
|
86
|
+
stop/start, delayed callbacks and H5 recovery against the exact reproduction and
|
|
87
|
+
candidate-fix firmware identities.
|
|
88
|
+
|
|
65
89
|
## Artifact discipline
|
|
66
90
|
|
|
67
|
-
|
|
91
|
+
Follow [firmware-delivery.md](firmware-delivery.md). Record the explicit firmware
|
|
92
|
+
version, application-BIN SHA-256 and descriptor/full ELF SHA-256 for every build
|
|
93
|
+
used in HIL. Runtime evidence applies only to the exact artifact. Diagnose one
|
|
94
|
+
failing invariant, make the smallest correction, rerun that layer, and preserve
|
|
95
|
+
the comparison in the report.
|
|
68
96
|
|
|
69
97
|
Local intermediate snapshots may be ignored, but the Hardware IR, semantic
|
|
70
98
|
contracts, `dependencies.lock`, custom partition input, and the artifact named
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Product controls, reset, and power
|
|
2
|
+
|
|
3
|
+
Read this reference when the product has buttons, touch inputs, reset controls,
|
|
4
|
+
power keys, wake sources, or enclosure labels. Concrete pins and electrical
|
|
5
|
+
behavior belong in the exact board/carrier evidence and adapter, never in this
|
|
6
|
+
Skill.
|
|
7
|
+
|
|
8
|
+
## Identify the physical product, not just the baseboard
|
|
9
|
+
|
|
10
|
+
A retail or battery-powered device may combine a compute board with a carrier,
|
|
11
|
+
PMIC, latch circuit, flex PCB, or enclosure controls that are absent from the
|
|
12
|
+
baseboard schematic. When a user's physical observation conflicts with the
|
|
13
|
+
available schematic, treat it as evidence of a missing or different variant.
|
|
14
|
+
Do not declare a working control nonexistent. Request or inspect the exact
|
|
15
|
+
carrier schematic, PCB markings, photographs, BSP definitions, or safe probe
|
|
16
|
+
results and keep the unresolved mapping explicit.
|
|
17
|
+
|
|
18
|
+
Classify each physical label before assigning software behavior:
|
|
19
|
+
|
|
20
|
+
- MCU-readable GPIO button or touch input;
|
|
21
|
+
- boot-strapping input;
|
|
22
|
+
- reset/enable line;
|
|
23
|
+
- PMIC or hardware power-latch control;
|
|
24
|
+
- I/O-expander input;
|
|
25
|
+
- indicator with no input function;
|
|
26
|
+
- unknown control on a missing board layer.
|
|
27
|
+
|
|
28
|
+
For an MCU-readable input, record the SoC GPIO, active level, external pull,
|
|
29
|
+
debounce requirement, shared owner, wake capability, and any strapping role.
|
|
30
|
+
Holding a strapping pin during reset can select a boot mode. A reset/enable line
|
|
31
|
+
normally resets the MCU and cannot also be treated as an application button.
|
|
32
|
+
A PMIC/latch power key and an MCU “enter deep sleep” action are different
|
|
33
|
+
product contracts; do not substitute one for the other without circuit evidence.
|
|
34
|
+
|
|
35
|
+
## Keep controls behind a narrow adapter
|
|
36
|
+
|
|
37
|
+
Use a board/product-controls component to own GPIO setup, polling or ISR work,
|
|
38
|
+
debounce, gestures, and boot-held suppression. It emits bounded product intents
|
|
39
|
+
such as `AI_TOGGLE_REQUESTED`; it does not call TiRTC, HTTP, MQTT, media, or
|
|
40
|
+
session lifecycle APIs from an ISR or polling callback.
|
|
41
|
+
|
|
42
|
+
Prefer one `AI_TOGGLE_REQUESTED` event whose start/stop decision is serialized by
|
|
43
|
+
the state-owning runtime. If the existing runtime exposes only separate start
|
|
44
|
+
and stop intents, the adapter may map a public state snapshot to one of them,
|
|
45
|
+
but the runtime must validate the intent again against its authoritative state.
|
|
46
|
+
Define whether rapid gestures are queued, coalesced, or rejected so two reads of
|
|
47
|
+
the same stale snapshot cannot silently violate the product behavior.
|
|
48
|
+
|
|
49
|
+
The runtime remains responsible for session generation, callback ordering,
|
|
50
|
+
media ownership, timeouts, cleanup, and late-event rejection. A toggle must
|
|
51
|
+
define behavior for waiting, connecting, active, stopping, H5-owned, and
|
|
52
|
+
error/recovery states instead of maintaining a second Boolean inside the button
|
|
53
|
+
driver.
|
|
54
|
+
|
|
55
|
+
## Deterministic button behavior
|
|
56
|
+
|
|
57
|
+
For a mechanical active-low or active-high input, require all of the following:
|
|
58
|
+
|
|
59
|
+
- a stable active interval before one press event;
|
|
60
|
+
- no repeat event until a stable release;
|
|
61
|
+
- a button already held during boot must be released before it can trigger;
|
|
62
|
+
- short/long-press thresholds have an explicit product meaning;
|
|
63
|
+
- queue overflow or rejected intents are logged and recover safely;
|
|
64
|
+
- polling tasks and ISRs stay bounded and never block on network/session work.
|
|
65
|
+
|
|
66
|
+
Test boot-held, bounce, rapid repeated presses, press during connection, press
|
|
67
|
+
during active audio, press during stop, delayed SDK callbacks, and recovery to
|
|
68
|
+
H5 or waiting state. For a battery product, separately test cold power-on,
|
|
69
|
+
software shutdown/deep sleep, wake, charging/USB behavior, and reset; a passing
|
|
70
|
+
AI toggle does not prove the power path.
|
|
71
|
+
|
|
72
|
+
Keep debounce and gesture state transitions separable from GPIO/RTOS plumbing
|
|
73
|
+
so host tests can prove boot-held suppression, one event per stable press,
|
|
74
|
+
release re-arming, and the selected rapid-gesture policy. Add a focused runtime
|
|
75
|
+
test for stale or duplicate control intents whenever the runtime performs the
|
|
76
|
+
authoritative state validation.
|
|
@@ -13,16 +13,20 @@ Use [the report template](../assets/report-template.md) and preserve separate `P
|
|
|
13
13
|
| L3 Online | Wi-Fi provisioning, binding, MQTT, and TiRTC reach ready state |
|
|
14
14
|
| L4 Media | Camera/microphone/speaker local paths work and counters/measurements are captured |
|
|
15
15
|
| L5 H5 | Browser receives the declared video/audio and talkback reaches the device |
|
|
16
|
-
| L6
|
|
16
|
+
| L6 Sessions | AI, device-call and WeChat VoIP requested flows work; simultaneous capture/playback, AEC/double-talk, stop, timeout and H5 recovery are observed separately |
|
|
17
17
|
| L7 Stability | Requested weak-network, repeated-session, resource, and soak criteria pass |
|
|
18
18
|
|
|
19
|
-
Run and record the intake assessment before L0, the build assessment with `--project` and the exact artifact SHA-256 at L1, and the HIL assessment only when matching runtime evidence exists.
|
|
19
|
+
Run and record the intake assessment before L0, the build assessment with `--project` and the exact artifact SHA-256 at L1, and the HIL assessment only when matching runtime evidence exists. Follow [firmware-delivery.md](firmware-delivery.md) for artifact location, retention, and mode-transition rules. Record actual byte size and SHA-256 in `build_evidence.artifacts[]`; the assessor reopens the file and rejects stale metadata. Missing serial or browser access is a `SKIP` for the affected L2-L7 levels, not an L0/L1 failure.
|
|
20
20
|
|
|
21
|
-
Keep `COMPILE_PASS` separate from `BUILD_VERIFIED`. When the compiler succeeds but a required runtime, audio, or video semantic gate fails or is missing, record the compiler result and report the feature and project as blocked.
|
|
21
|
+
Keep `COMPILE_PASS` separate from `BUILD_VERIFIED`. When the compiler succeeds but a required runtime, audio, or video semantic gate fails or is missing, record the compiler result and report the feature and project as blocked. H5 image display is L5 evidence, never an inference from L1.
|
|
22
22
|
|
|
23
23
|
## Evidence
|
|
24
24
|
|
|
25
|
-
Record exact board revision, selected media, Wi-Fi, and binding profiles,
|
|
25
|
+
Record exact board revision, selected media, Wi-Fi, and binding profiles,
|
|
26
|
+
toolchain and SDK versions, source/adapter revisions, commands, return codes,
|
|
27
|
+
firmware version, application-BIN SHA-256, descriptor/full ELF SHA-256, serial
|
|
28
|
+
port/chip, sanitized log paths, browser or platform observations, and every
|
|
29
|
+
unavailable dependency. Never conflate the BIN and ELF hashes.
|
|
26
30
|
|
|
27
31
|
Runtime evidence belongs to one artifact. Label superseded artifacts and keep their observations as history; do not promote them to the current BIN/ELF. For HIL assessment, add the full SHA-256 to `runtime_evidence` and run `hardware_ir.py assess --phase hil --artifact-sha256 <sha> --strict`.
|
|
28
32
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# TiRTC runtime protocol contract
|
|
2
2
|
|
|
3
|
-
Use this gate for every generated H5/AI project. It verifies protocol behavior that is
|
|
3
|
+
Use this gate for every generated H5/AI/call/VoIP project. It verifies protocol behavior that is
|
|
4
4
|
neither a board clock fact nor a camera fact: service discovery wiring, SDK callback
|
|
5
5
|
lifecycle, stream/media metadata, and AI session negotiation.
|
|
6
6
|
|
|
@@ -30,5 +30,15 @@ The gate requires all of the following:
|
|
|
30
30
|
- AI media starts only after a matching response provides a non-empty session ID and
|
|
31
31
|
authoritative input/output audio formats matching the implemented codec;
|
|
32
32
|
- remote `end_session` converges through the runtime control task.
|
|
33
|
+
- requested device-call/WeChat VoIP endpoints, MQTT event names, `call`/`wxcall`
|
|
34
|
+
commands and their pinned `tirtc-server-example` protocol revision are present
|
|
35
|
+
in implementation files;
|
|
36
|
+
- one foreground-session arbiter owns STREAM/AI/CALL/VOIP state, allows one
|
|
37
|
+
pending request, rejects stale generations, uses monotonic deadlines, defers
|
|
38
|
+
lifecycle work outside callbacks and restores H5 after foreground calls.
|
|
33
39
|
|
|
34
|
-
|
|
40
|
+
For device-call or WeChat VoIP, populate the example contract's `business`
|
|
41
|
+
section. An empty `business.features` list remains valid for H5/AI-only projects,
|
|
42
|
+
but cannot satisfy Hardware IR that requests `device_call` or `wechat_voip`.
|
|
43
|
+
|
|
44
|
+
Compilation without this gate is not an H5/AI/call/VoIP `BUILD_VERIFIED` result.
|