Skip to content

Merge all 50 codex PRs (#4–#58) into v0.6 (MeshCore) + security/regression fixes#59

Merged
ItsLimitlezz merged 114 commits into
mainfrom
v0.6-meshcore-public
Jun 20, 2026
Merged

Merge all 50 codex PRs (#4–#58) into v0.6 (MeshCore) + security/regression fixes#59
ItsLimitlezz merged 114 commits into
mainfrom
v0.6-meshcore-public

Conversation

@ItsLimitlezz

Copy link
Copy Markdown
Owner

Merges all 50 open codex PRs (#4#58) into the v0.6 line, reconciling the
heavy overlap between independently-generated branches and fixing two issues
found during integration.

Verification

Every merge was built on both targets before commit:

  • pio run -e native--selftest (CODEC: all passed) + --simtest (SIM SCENARIO: all passed)
  • pio run -e tdeck with MeshCore on and off

Final T-Deck budget (MeshCore on): RAM 70.3%, Flash 30.1%.

Fixes beyond a plain merge

Notable reconciliations (schema cluster)

50 merge commits + reconciliation/fix commits.

🤖 Generated with Claude Code

ItsLimitlezz and others added 27 commits June 19, 2026 20:19
# Conflicts:
#	src/serial_cli.cpp
#	src/services/feedback.c
# Conflicts:
#	sim/main_sim.c
#	src/serial_cli.cpp
#	src/services/mesh_core.c
# Conflicts:
#	sim/main_sim.c
#	src/services/mesh_core.c
#	src/services/store.c
# Conflicts:
#	sim/main_sim.c
#	src/serial_cli.cpp
#	src/services/mesh_core.c
The native-only merge loop never compiled serial_cli.cpp (it is #ifdef
LZ_TARGET_TDECK), so union-merge corruption went undetected:
  - cmd_nodes lost its body to an orphaned signature; reattached as
    cmd_nodes(char*) and dropped the stray cmd_nodes(void).
  - two cmd_app definitions (catalog #16 + notify #15) collapsed into one
    that handles both 'app notify test' and 'app catalog status|test'.
  - forward-declared cmd_feedback so cmd_app can echo feedback status.

Both targets build: native (selftest+simtest) and tdeck MeshCore (RAM 70.2%).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts:
#	sim/main_sim.c
#	src/services/store.c
Fix HIGH path-traversal in safe_id(): it allowed '.' and '..' (the '..'
guard existed only in safe_entry). Since an app id becomes a path segment
(apps/<id>/...), id='..' escaped the apps root. safe_id now rejects a lone
'.' and any '..' substring. Verified: '..','../../etc','a..b' rejected;
'abc','my.app','good_id-1' allowed.
Reconciled with #38's install/promotion: unified the recursive-delete
helper on #39's generic remove_tree*/LZ_APP_REMOVE_MAX_* naming (renamed
#38's path_remove_tree callers to match), kept both the install-temp and
retained directory filters in the app scanners, and preserved #37's catalog
validators that #39's branch predated. Both targets build.
Merged #40's update-available status badge with #35's permissions/access
rows: catalog rows show version (v%s), detail view computes status via
local_app_update_for() and keeps the Access summary row (8-field grid).
Closed remove_tree() with its own return tail so #41's save/load/clear
catalog-cache functions land as separate definitions (not sharing #39's
function tail). mesh_core + sim selftest resolved additively.
Merged #43's 'ota boot-policy/boot-test' into the existing cmd_ota
(manifest status/test) instead of a duplicate definition; forward-declared
ota_print_decision and removed the duplicate dispatch arm.
Kept both #44's app_session_fault helper and the runtime-budget functions;
app_session_fail both refreshes runtime and records the fault. Fixed a
merge-order bug where the union placed #44's fault-capture test after
lz_store_stop_local_app() had zeroed the live session — moved it before
teardown so action_fault copies a live session. Both targets build, sim green.
Adopted #52's per-line 'v2|' schema tag for nodes.db (replacing the old
'# lz_nodes' header line) and taught HEAD's node_parse_line helper to skip
the tag / reject future schemas, keeping #51's regression-test structure.
Updated the node-format selftest to assert the v2 tag and the settings
selftest to assert v4 (bumped by #36). Both targets build, sim green.
# Conflicts:
#	.github/workflows/firmware.yml
Kept #58's 'rxlog [on|off]' help line alongside HEAD's 'nodes [test]'
(node DB schema test still present). Both targets build.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9bb1279ad9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/services/store.c

char schema[32];
if(!json_get_string_bounded(json, "schema", schema, sizeof schema) ||
strcmp(schema, "limitlezz.app_catalog.v1") != 0) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Accept the catalog schema validated by CI

When a catalog follows the new network-catalog docs and CI validator (limitlezz.app.catalog.v1 with package_url, package_sha256, package_bytes, and object compatibility), the on-device validator rejects it immediately as bad schema because it still requires limitlezz.app_catalog.v1. This means a catalog that passes scripts/validate_app_catalog.py docs/examples/app-catalog-index.json will fail app catalog status when copied to catalog/index.json, so the published catalog contract cannot be consumed by firmware.

Useful? React with 👍 / 👎.

Comment thread src/services/mesh_core.c
size_t klen = strlen(key);
while(mc0_next_token(&p, tok, sizeof tok)) {
if(strncmp(tok, key, klen) == 0 && tok[klen] == '=') {
mc0_decode_value(tok + klen + 1, out, cap);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject overlong MC0 text before truncating

For SEND_PUBLIC and SEND_DM, mc0_get_arg decodes the text= token into a LZ_TEXT_MAX + 1 buffer and silently truncates it before the later strlen(text) > LZ_TEXT_MAX checks run. When an MC0 client sends more than the advertised max_text=200 bytes, the command is accepted and a truncated message is sent instead of returning text_too_long, which can corrupt user-visible messages without telling the companion app.

Useful? React with 👍 / 👎.

check_tdeck_budget.py parses RAM as '(used N bytes from M bytes)', which
PlatformIO only prints in the build summary. The tdeck budget step passed it
'pio run -e tdeck -t size' output — the GNU text/data/bss table with no RAM
line — and since the firmware was already built in the prior step, -t size
was cached and never reprinted the summary, so the gate died with 'RAM usage
line not found'. Point it at tdeck-build.txt (the build log, which has the
RAM line), matching the already-correct tdeck-meshcore budget step. Verified
both budgets pass locally (RAM 230,196/307,200; firmware ~30% of OTA slot).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ItsLimitlezz ItsLimitlezz merged commit b3101f1 into main Jun 20, 2026
1 check 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.

2 participants