Skip to content

Refactor/log media sampler - #40

Merged
sedawwk merged 5 commits into
masterfrom
refactor/log-media-sampler
Sep 21, 2026
Merged

sedawwk merged 5 commits into
masterfrom
refactor/log-media-sampler

Conversation

@heshaoqiong-tuya

@heshaoqiong-tuya heshaoqiong-tuya commented Sep 20, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Five commits finish the log refactor. End state: the SDK holds no runtime log state at all — the level is a compile-time ceiling (one SDK-wide, optionally lowered per module), the destination is a compile-time macro, and what compiles in is what emits.

  • a7c0369 feat(log)!: compile-time-only logging + AGENTIC_KIT_LOG destination remap — one SDK-wide ceiling AGENTIC_KIT_LOG_LEVEL (0–4, default 4) gates every SDK log macro via the new log_tag_* facade in common/log.h; module code no longer calls log_emit() directly and CI rejects new raw call sites. rtc-tcp-client packet logging picks its INFO/DEBUG sink at compile time (sampling builds have exactly one level; flood mode needs AGENTIC_KIT_TAI_LOG_MEDIA_SAMPLE_N=0 plus a DEBUG ceiling) and its JSON formatter compiles out below INFO — a compile-matrix test sweeps the level × sampling combinations. On top of that, #define AGENTIC_KIT_LOG(level, tag, fmt, ...) is the single destination switch, riding the same integrator pickup as every knob (agentic_kit_config.h / -D / AGENTIC_KIT_USER_CONFIG, first-definition-wins). This is the idiom lwIP (LWIP_PLATFORM_DIAG) and mbedTLS offer: bridging into ESP_LOGx/Zephyr LOG_* no longer needs a vsnprintf-into-buffer round trip, format checking stays in the target macro, and the sink receives the module tag as its own token (per-tag filtering and structured sinks become possible). log_set_level() / log_get_level(), the tai_*_log_level() wrappers, log_set_handler(), log_fn_t and the public log_default_handler() are all gone; a sink written as a function reuses the default stderr output via the new log_emit_valist() (the esp_log_writev role). The docs-audit round is folded in here where it owns the prose: the architecture page's common table lists the log facade, the agent-trigger -v row matches the binary (a compile-time notice, not a runtime switch), the rtc-client reference scopes its runtime logging outside the compile-time facade, and the log.h comment names the tags actually emitted.
  • 42591a3 refactor(iot): log_error family -> IOT_LOG* — iot-client's unprefixed log_error/log_warn/log_info/log_debug become IOT_LOGE/LOGW/LOGI/LOGD, following the module-prefix convention of the other private vocabularies (TAI_LOG*, TUYA_BLE_HAL_LOG*). Pure rename over 342 call sites; prose in log.h / AGENTS.md / the knobs guide synced, and the iot_atop_call() sample (header + atop-generic-call guide, both locales) now logs through the public log_tag_error("app", ...) facade instead of the src-private log_error() — not IOT_LOGE, which is src-private too, so the copied sample never compiled from an iot_atop.h-only TU (compile-probed in the docs-audit round). The old names read like facade API and had already leaked into integrator-facing samples.
  • 41723f1 feat(log): per-module log ceilings AGENTIC_KIT_{IOT,TAI,TUYA_BLE}_LOG_LEVEL — quiet one module without touching the SDK-wide ceiling (iot-client at info while rtc-tcp-client stays debug). Each knob lives in its module's *_config_defaults.h, #ifndef-defaults to the global ceiling, and is lower-only (effective ceiling = min(global, module), clamped to the global once in the module's config file so block-level gates see the effective ceiling); the facade gate still applies, so a remap can never resurrect a compiled-out line. The clamp closes the hole the adversarial-verify review round caught: block-level gates (the packet-log formatter, the flood branch, tuya-ble's HEXDUMP body) keyed on the knob alone, so a module value above the global ceiling compiled dead code back in (a 19KB formatter behind ((void)0) dispatches, -Werror breaks). tuya-ble gains its first knob and its tuya_ble_config_defaults.h. Tests: tai_log_module_zero_tests keeps probing the facade while only the module is lowered; the compile matrix grows a tai_level dimension plus module-above-global clamp probes (19 combos); log-only parameters that turn unused under a lowered module ceiling get (void) suppressions so integrator -Wextra -Werror builds stay clean. Default builds verified byte-identical. The docs-audit round is folded in here for the two pages this commit last touched: the knobs guide's AGENTIC_KIT_LOG example compiles as printed (real level mapping, no undefined lvl_of()), the tag list matches the emitted tags, a function-sink example shows log_emit_valist() takes no tag — fold "[tag] " into the format string — and the rtc-tcp-client reference documents the flood recipe plus the ceiling-3/sampling-0 silence trap.
  • d9b2e5b chore(review) — two-axis review findings folded in: tai_log_module_zero_tests joins the CI valgrind loop, a stale "runtime-chosen level" sentence leaves AGENTS.md, and core_mqtt_config.h's cross-reference points at its surviving sibling.
  • d52dccb docs(changelog) — BREAKING entries plus the PR-number backfill, at the tip. Carries the docs-audit round's CHANGELOG fix: the flood knob is spelled AGENTIC_KIT_TAI_LOG_MEDIA_SAMPLE_N again (the missing TAI_ segment defined a dead macro and silently kept 1/50 sampling).

BREAKING — migration

Before After
-DTAI_LOG_LEVEL=N (rtc-tcp-client), dead -DLOG_LEVEL -DAGENTIC_KIT_LOG_LEVEL=N — silences the whole SDK at compile time
log_set_level() / log_get_level(), tai_set_log_level() / tai_get_log_level() a lower ceiling at build time, or level filtering inside your AGENTIC_KIT_LOG target
log_set_handler(fn) / log_fn_t / public log_default_handler() make that function the AGENTIC_KIT_LOG target — it now receives the level and the bare tag directly

After migrating, a single module can be quieted further without touching the rest: -DAGENTIC_KIT_{IOT,TAI,TUYA_BLE}_LOG_LEVEL=N — lower-only, defaults to the global ceiling.

What the ESP-IDF pair-by-ble example now ships (examples/esp-idf/components/agentic_kit/kit_opts/agentic_kit_config.h):

#define AGENTIC_KIT_LOG(level, tag, fmt, ...)                                   \
    ESP_LOG_LEVEL_LOCAL((level) == LOG_ERROR ? ESP_LOG_ERROR :                  \
                        (level) == LOG_WARN  ? ESP_LOG_WARN :                   \
                        (level) == LOG_INFO  ? ESP_LOG_INFO :                   \
                                              ESP_LOG_DEBUG,                    \
                        tag, fmt, ##__VA_ARGS__)

A sink written as a plain variadic function calls log_emit_valist(level, fmt, args) for the default stderr output instead of re-implementing it.

Two ground rules from the guide (docs/guides/compile-time-knobs.md):

  • The AGENTIC_KIT_LOG_LEVEL ceiling still gates — log_tag_* collapse to ((void)0) above it (arguments never evaluated), so a remap cannot resurrect compiled-out lines.
  • There is no runtime fallback: the remap must reach every target that compiles SDK sources — including the vendored coreHTTP/coreMQTT, whose logs route into the facade via common/core_{http,mqtt}_config.h.

Tests & build wiring

The SDK's own tests migrated to the shape they prescribe to integrators: each test build's log_config/agentic_kit_config.h remaps AGENTIC_KIT_LOG into one test_log_sink whose PASSTHROUGH / CAPTURE / QUIET / COUNT are modes, not handler swaps (capture rebuilds the "[tag] " prefix, with va_copy and truncation discipline carried over). The wiring lesson on the CMake side: compiled outside the remap, the vendored coreHTTP/coreMQTT lines bypass the sink — exactly what the runtime handler used to catch library-agnostically — so the tuya_iot_client_testlog variant compiles them in alongside the iot sources, and the ble sources compile into the test executable the same way. The plain tuya_iot_client / core_http / core_mqtt targets are untouched: the examples' link path and output stay byte-identical. TAI_LOOPBACK_VERBOSE keeps its name and default-silent behavior (now test_log_env_default()).

Docs follow in both locales: the knobs guide, the iot-client / rtc-tcp-client reference pages, the public header notes, and the AGENTS.md maintainer guide.

@heshaoqiong-tuya
heshaoqiong-tuya marked this pull request as draft September 20, 2026 06:04
@heshaoqiong-tuya
heshaoqiong-tuya force-pushed the refactor/log-media-sampler branch from 5caba79 to 399e6f6 Compare September 20, 2026 07:41
@heshaoqiong-tuya
heshaoqiong-tuya marked this pull request as ready for review September 20, 2026 07:41
heshaoqiong-tuya added a commit that referenced this pull request Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log
  sink selection under it.
- Backfill (#35) on the five entries that landed through the
  ble-pair-improve2 follow-up.
- Drop the last two (PR pending) markers: 7e07e35 (docs-site English)
  and 2afba8f (tuya-ble dedup) entered master without a PR -- via a
  local eng-doc merge and a direct push respectively.

Co-Authored-By: Claude Code <[email protected]>
@heshaoqiong-tuya
heshaoqiong-tuya force-pushed the refactor/log-media-sampler branch from 399e6f6 to 9082201 Compare September 20, 2026 08:14
heshaoqiong-tuya added a commit that referenced this pull request Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log
  sink selection under it.
- Backfill (#35) on the five entries that landed through the
  ble-pair-improve2 follow-up.
- Drop the last two (PR pending) markers: 7e07e35 (docs-site English)
  and 2afba8f (tuya-ble dedup) entered master without a PR -- via a
  local eng-doc merge and a direct push respectively.

Co-Authored-By: Claude Code <[email protected]>
@heshaoqiong-tuya
heshaoqiong-tuya force-pushed the refactor/log-media-sampler branch from 9082201 to b1ad492 Compare September 20, 2026 09:56
heshaoqiong-tuya added a commit that referenced this pull request Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log
  sink selection under it.
- Backfill (#35) on the five entries that landed through the
  ble-pair-improve2 follow-up.
- Drop the last two (PR pending) markers: 7e07e35 (docs-site English)
  and 2afba8f (tuya-ble dedup) entered master without a PR -- via a
  local eng-doc merge and a direct push respectively.

Co-Authored-By: Claude Code <[email protected]>
@heshaoqiong-tuya
heshaoqiong-tuya force-pushed the refactor/log-media-sampler branch from b1ad492 to 243e61b Compare September 20, 2026 10:34
@heshaoqiong-tuya
heshaoqiong-tuya marked this pull request as draft September 20, 2026 11:08
heshaoqiong-tuya added a commit that referenced this pull request Sep 20, 2026
The one open-source idiom the facade was missing. The runtime
log_set_handler() sink hands the customer fmt + va_list, and a va_list
cannot be forwarded to a macro — so bridging into macro-based logging
systems (ESP-IDF ESP_LOGx, Zephyr LOG_*) forced a
vsnprintf-into-buffer, "%s"-back-out round trip: an extra copy, an
extra truncation point, and the target macro's format checking lost.
lwIP's LWIP_PLATFORM_DIAG and mbedTLS's printf-macro config are this
mechanism; the facade now has it too.

AGENTIC_KIT_LOG(level, tag, fmt, ...) is the one remap point, guarded
by #ifndef right after the ceiling so it rides the existing integrator
pickup (the same agentic_kit_config.h / -D / AGENTIC_KIT_USER_CONFIG
channel as every knob — zero new mechanism). log_tag_* become thin
forwarders, so one definition takes over the whole SDK (iot-client's
log_error family, TAI_LOG*, TUYA_BLE_HAL_LOG* all funnel through
log_tag_*), and the customer receives the tag as its own token —
structured sinks and per-tag filtering become possible where the
handler only ever saw the tag folded into the format string.

Ground rules, binding both directions: the AGENTIC_KIT_LOG_LEVEL
ceiling still gates (log_tag_* collapse to ((void)0) above it, so a
remap cannot resurrect compiled-out lines and their arguments are
never evaluated); a remap bypasses log_emit, so log_set_handler() no
longer sees those lines — pick one per build. The default expansion is
byte-identical to the previous direct log_emit call, keeping its
format(printf) checking.

Documents the mechanism in the knobs guide (zh+en, new anchor-checked
section), the CHANGELOG #40 entry, and the two public headers' logging
notes. The runtime handler stays — this is an addition, not a
replacement.

Verified: a pickup probe through agentic_kit_config.h (level-4 build
sees info dispatched into the customer macro with the bare tag; a
LEVEL=1 build compiles a struct-argument debug call site — arguments
unevaluated — and the sink never sees info); full host build including
examples; the CI leak grep clean; ctest 17/17; the docs-site builds
clean in both locales (check:i18n included).

Co-Authored-By: Claude Code <[email protected]>
heshaoqiong-tuya added a commit that referenced this pull request Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log
  sink selection under it.
- Backfill (#35) on the five entries that landed through the
  ble-pair-improve2 follow-up.
- Drop the last two (PR pending) markers: 7e07e35 (docs-site English)
  and 2afba8f (tuya-ble dedup) entered master without a PR -- via a
  local eng-doc merge and a direct push respectively.

Co-Authored-By: Claude Code <[email protected]>
@heshaoqiong-tuya
heshaoqiong-tuya force-pushed the refactor/log-media-sampler branch from bd05c05 to f4fb70e Compare September 20, 2026 12:07
heshaoqiong-tuya added a commit that referenced this pull request Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log
  sink selection under it.
- Backfill (#35) on the five entries that landed through the
  ble-pair-improve2 follow-up.
- Drop the last two (PR pending) markers: 7e07e35 (docs-site English)
  and 2afba8f (tuya-ble dedup) entered master without a PR -- via a
  local eng-doc merge and a direct push respectively.

Co-Authored-By: Claude Code <[email protected]>
@heshaoqiong-tuya
heshaoqiong-tuya force-pushed the refactor/log-media-sampler branch from f4fb70e to 15021f5 Compare September 20, 2026 12:25
heshaoqiong-tuya added a commit that referenced this pull request Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log
  sink selection under it.
- Backfill (#35) on the five entries that landed through the
  ble-pair-improve2 follow-up.
- Drop the last two (PR pending) markers: 7e07e35 (docs-site English)
  and 2afba8f (tuya-ble dedup) entered master without a PR -- via a
  local eng-doc merge and a direct push respectively.

Co-Authored-By: Claude Code <[email protected]>
@heshaoqiong-tuya
heshaoqiong-tuya force-pushed the refactor/log-media-sampler branch from 15021f5 to f4935a2 Compare September 20, 2026 12:36
heshaoqiong-tuya added a commit that referenced this pull request Sep 21, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log
  sink selection under it.
- Backfill (#35) on the five entries that landed through the
  ble-pair-improve2 follow-up.
- Drop the last two (PR pending) markers: 7e07e35 (docs-site English)
  and 2afba8f (tuya-ble dedup) entered master without a PR -- via a
  local eng-doc merge and a direct push respectively.

Co-Authored-By: Claude Code <[email protected]>
@heshaoqiong-tuya
heshaoqiong-tuya force-pushed the refactor/log-media-sampler branch from f4935a2 to 321acb1 Compare September 21, 2026 06:55
heshaoqiong-tuya and others added 5 commits September 21, 2026 17:09
…emap

The log refactor landed as two stages, squashed here: first the
SDK-wide compile-time ceiling, then the macro-only destination remap
that removes the last runtime log state. End state: the level is a
compile-time fact, the destination is a compile-time fact, and what
compiles in is what emits.

Stage 1 -- compile-time-only logging across the SDK:

One SDK-wide compile-time log ceiling, AGENTIC_KIT_LOG_LEVEL (0-4,
default 4), gates every SDK log macro via the log_tag_* facade in
common/log.h; module code no longer calls log_emit() directly and CI
rejects new raw call sites.

- BREAKING -DTAI_LOG_LEVEL=N (rtc-tcp-client only) and the dead
  -DLOG_LEVEL move to -DAGENTIC_KIT_LOG_LEVEL=N, which now silences
  the whole SDK at compile time.
- BREAKING the runtime log layer is removed: log_set_level(),
  log_get_level() and the tai_set_log_level()/tai_get_log_level()
  wrappers are gone, and log_emit() no longer filters -- the ceiling is
  the only level gate, so what compiles in is what emits. Migrate
  runtime log_set_level(N) calls to a lower ceiling at build time, or
  to a level-dropping handler installed with log_set_handler().
- rtc-tcp-client packet logging selects its INFO/DEBUG sink at compile
  time (sampling builds have exactly one level; flood mode needs
  AGENTIC_KIT_TAI_LOG_MEDIA_SAMPLE_N=0 plus a DEBUG ceiling) and its
  JSON formatter compiles out below INFO. A compile-matrix test builds
  every supported level x sampling combination.

Stage 2 -- AGENTIC_KIT_LOG, macro-only remap for the log dispatch:

The one open-source idiom the facade was missing, and the follow-
through that makes it the only way in. A va_list cannot be forwarded
to a macro, so bridging the old runtime handler into macro-based
logging systems (ESP-IDF ESP_LOGx, Zephyr LOG_*) forced a
vsnprintf-into-buffer, "%s"-back-out round trip: an extra copy, an
extra truncation point, and the target macro's format checking lost.
lwIP's LWIP_PLATFORM_DIAG and mbedTLS's printf-macro config are this
mechanism; the facade now has it -- as the single dispatch point.

AGENTIC_KIT_LOG(level, tag, fmt, ...) is guarded by #ifndef right
after the ceiling so it rides the existing integrator pickup (the
same agentic_kit_config.h / -D / AGENTIC_KIT_USER_CONFIG channel as
every knob -- zero new mechanism). log_tag_* become thin forwarders,
so one definition takes over the whole SDK (iot-client's log_error
family, TAI_LOG*, TUYA_BLE_HAL_LOG* all funnel through log_tag_*),
and the customer receives the bare module tag as its own token --
structured sinks and per-tag filtering become possible where the
handler only ever saw it folded into the format string. Ground
rules: the AGENTIC_KIT_LOG_LEVEL ceiling still gates (log_tag_*
collapse to ((void)0) above it, arguments never evaluated), and the
remap must reach every target that compiles SDK sources -- there is
no runtime dispatch left to fall back on.

Because there is none: log_set_handler(), log_fn_t and the public
log_default_handler() are gone, and the SDK holds no mutable log
state at all (the benign-race handler pointer included). What varied
at runtime via handler install/uninstall becomes a mode inside the
one sink a build names; a sink implemented as a variadic function
reaches the new log_emit_valist() (the esp_log_writev role) to reuse
the default stderr output instead of re-implementing it.

Tests migrated to the same shape they now prescribe to integrators:
each test build's log_config/agentic_kit_config.h remaps
AGENTIC_KIT_LOG into one test_log_sink whose PASSTHROUGH / CAPTURE /
QUIET / COUNT are modes, not handler swaps -- test_core counts
through it, mqtt/atop capture through it (tag prefix rebuilt,
va_copy and truncation discipline carried over), test_prov goes
quiet through it, test_wire scans the captured window, and
tai_pal_loopback's lb_log env gate folds into test_log_env_default
(TAI_LOOPBACK_VERBOSE keeps its name and default-silent behavior).
The wiring lesson that shaped the CMake side: the vendored
coreHTTP/coreMQTT sources route their logs into the facade via
common/core_{http,mqtt}_config.h, so they are part of the SDK's
logging surface -- compiled outside the remap their lines bypass the
sink (exactly what a runtime handler used to catch
library-agnostically). The tuya_iot_client_testlog variant therefore
compiles them in alongside the iot sources; the ble sources compile
into the test executable the same way. The plain tuya_iot_client,
core_http and core_mqtt targets are untouched -- the examples' link
path and output are byte-identical.

The ESP-IDF pair-by-ble example drops its runtime callback for the
macro: kit_opts/agentic_kit_config.h maps the facade onto
ESP_LOG_LEVEL_LOCAL with a compile-time level ternary, and each line
keeps its real module tag instead of one shared "tuya_ble" tag.
Docs follow in both locales (destination is a compile-time fact),
plus the public header notes and the CHANGELOG BREAKING entry.

Verified: pickup probes at both ceilings against the final log.c;
full host build including examples; the CI leak grep clean; ctest
17/17 serial (capture assertions included); TAI_LOOPBACK_VERBOSE
gate (0 stderr lines by default, 742 with it set); docs-site builds
in both locales.

Docs-audit fold (usage/impact round, zh+en): the architecture
page's common-components table gains the log-facade row (common/log.h
+ common/log.c); the agent-trigger tutorial's -v row matches the
binary -- it prints a compile-time notice, not a runtime switch; the
rtc-client reference scopes its on_log / stm_open_set_log_level
runtime logging outside the compile-time facade (prebuilt library,
not compiled from source); and the log.h remap comment lists the tags
actually emitted -- the "tai" tag never existed, rtc-tcp-client
passes per-source-file tags.

Co-Authored-By: Claude Code <[email protected]>
The iot-client call-site vocabulary was the only log family in the
SDK without a module prefix (log_error/log_warn/log_info/log_debug)
and the only one that is neither public API nor porting contract --
private sugar squatting on generic names. Two costs, one already
realized: the names read like facade API (common/log.h owns
log_tag_*; nothing named log_error exists for a reader), and they
leaked into integrator-facing samples (the iot_atop.h doc comment
and the atop-generic-call guide taught log_error(...) -- a macro
that lives in src-private iot_internal.h and never compiled for
integrators).

Renamed to IOT_LOGE/LOGW/LOGI/LOGD, matching the module-prefix
convention the other vocabularies already follow (TAI_LOG*,
TUYA_BLE_HAL_LOG*), fixed tag "iot", 1:1 level mapping unchanged --
a pure rename, zero behavior change: 342 call sites across 14 src
files, plus the prose that names the family (common/log.h ceiling
comments, AGENTS.md scenarios and the log-gate note, the
compile-time-knobs guide zh+en), and the sample logging follows: the
iot_atop_call() example (header doc comment + atop-generic-call
guide, both locales) now logs through the public log_tag_error("app",
...) facade instead of the src-private log_error() -- not IOT_LOGE,
which is src-private too (iot_internal.h): a copied sample teaching
either never compiled from an iot_atop.h-only TU (docs-audit round,
compile-probe: IOT_LOGE undeclared, log_tag_error clean under -Wall
-Wextra -Werror). The error-path comment notes the facade is callable
from application code and shares the SDK's compile-time ceiling and
dispatch.

Also reworded one iot_internal.h comment ("reads exactly like
printf().") that matched the CI leak-grep pattern in .gitlab-ci.yml
as a false positive and would have failed the pipeline.

Verified: full rebuild clean; serial ctest 17/17; leak grep clean;
docs-site builds in both locales.

Co-Authored-By: Claude Code <[email protected]>
…_LEVEL

Quiet one module without touching the SDK-wide AGENTIC_KIT_LOG_LEVEL:
iot-client can run at info while rtc-tcp-client stays at debug. Each
knob lives in its module's *_config_defaults.h, #ifndef-defaults to
the global ceiling, and is lower-only (effective ceiling =
min(global, module)) because the facade gate in log.h still applies
-- a remap can never resurrect a compiled-out line. Each config file
additionally clamps its knob to the SDK-wide ceiling right after the
#ifndef default, so gates keyed on the knob alone also see the
effective ceiling: the TAI block-level gates (the packet-log
formatter, the flood branch, the tai_log_packet call sites) and
tuya-ble's HEXDUMP body would otherwise compile dead code back in
when the module value sits above the global -- a 19KB formatter with
per-packet work behind ((void)0) dispatches, and -Werror builds
broke on unused variables inside the resurrected branches. With the
clamp, a too-high value is a true no-op at every gate. Default builds
stay byte-identical (verified by strip-comparing every object against
a stashed baseline, before and after the clamp).

- iot-client / rtc-tcp-client: gate the IOT_LOG* / TAI_LOG*
  vocabularies where they are defined, plus the six TAI module-internal
  direct gate sites
- tuya-ble: first knob via new include/tuya_ble_config_defaults.h;
  gate the HAL rebind in tuya_ble_internal.h (LOGI dispatches at
  debug, so its ceiling is 4, not 3)
- tests: tai_log_module_zero_tests proves the facade still dispatches
  while only the module is lowered; the pkt-log compile matrix gains a
  tai_level dimension plus module-above-global clamp probes (19 combos
  asserting a knob above the global compiles exactly as the lower
  global ceiling alone would)
- -Wextra: log-only parameters that turn unused under a lowered module
  ceiling get (void) suppressions (tai_transport x2, tuya_ble_prov,
  iot_on_boarding) -- integrator -Wextra -Werror builds stay clean
- docs: compile-time-knobs zh+en (22 knobs), module references zh+en,
  AGENTS.md, CHANGELOG, and the porting guide names tuya-ble's knob
  and defaults file

Verified: ctest 18/18 serial; (global 2, module 4) compiles
tai_pkt_log.c to the same empty 336-byte object as global 2 alone,
zero formatter symbols, -Wall -Wextra -Werror clean; tuya-ble
preprocessed output with the module raised is byte-identical to the
default.

Docs-audit fold (usage/impact round, zh+en): the knobs guide's
AGENTIC_KIT_LOG example compiles as printed (the real level-mapping
ternary, no undefined lvl_of()), the tag list matches the emitted
tags, and a function-sink example shows log_emit_valist() takes no
tag -- the macro folds "[tag] " into the format string or every line
loses its prefix; the rtc-tcp-client reference documents the flood
recipe (SAMPLE_N=0 + DEBUG ceiling) and the trap that ceiling 3 with
sampling 0 leaves middle frames with no logs at all.

Co-Authored-By: Claude Code <[email protected]>
- .gitlab-ci.yml: tai_log_module_zero_tests joins the valgrind loop
  (AGENTS.md invariant: every no-subprocess binary gets leak-checked)
- CMakeLists.txt: the matrix comment said eight configurations; it has
  been sixteen since the tai_level dimension -- now it also names the
  two sweeps
- AGENTS.md: drop the stale "runtime-chosen level" media-sampler
  sentence: sampling builds have exactly one level and no runtime
  level comparison exists anywhere
- core_mqtt_config.h: the same-shape cross-reference points at
  core_http_config.h; the iot_client_config_defaults.h log_* family
  it named no longer exists
- CHANGELOG + PR draft: the "every supported level x sampling
  combination" overclaim becomes the 16 combinations actually built

ctest 17/18 serial -- iot_ota_verify_test timed out under load from a
concurrent review job; it is a 0.01 s test and passes in isolation.

Co-Authored-By: Claude Code <[email protected]>
- Tag the compile-time-ceiling entry (#40) and record the packet-log
  sink selection under it.
- Backfill (#35) on the five entries that landed through the
  ble-pair-improve2 follow-up.
- Drop the last two (PR pending) markers: 7e07e35 (docs-site English)
  and 2afba8f (tuya-ble dedup) entered master without a PR -- via a
  local eng-doc merge and a direct push respectively.

- Fix the flood knob's spelling in the #40 entry:
  AGENTIC_KIT_LOG_MEDIA_SAMPLE_N -> AGENTIC_KIT_TAI_LOG_MEDIA_SAMPLE_N
  (docs-audit round; the missing TAI_ segment defined a dead macro and
  silently kept 1/50 sampling).

Co-Authored-By: Claude Code <[email protected]>
@heshaoqiong-tuya
heshaoqiong-tuya force-pushed the refactor/log-media-sampler branch from 321acb1 to d52dccb Compare September 21, 2026 09:12
@heshaoqiong-tuya
heshaoqiong-tuya marked this pull request as ready for review September 21, 2026 09:21
@sedawwk
sedawwk merged commit ff8e85c into master Sep 21, 2026
4 checks passed
@heshaoqiong-tuya
heshaoqiong-tuya deleted the refactor/log-media-sampler branch September 21, 2026 09:40
heshaoqiong-tuya added a commit that referenced this pull request Sep 24, 2026
SDK_VERSION agentic-kit_0.4.0 -> agentic-kit_0.5.0 via
tools/bump_version next --minor + release; CHANGELOG Unreleased
becomes [0.5.0] - 2026-09-24 (English edition, #35, #37, #38, #40,
#41 and the UEAZ fix). tuya_iot_client build verified.

Co-Authored-By: Claude Code <[email protected]>
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.

2 participants