Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Firmware

ASecurity

Use when working on the silken_net STM32 firmware — Soldier (sense→TinyML→Lorenz→encrypt→TX, STOP2 loop) and Queen (LoRa RX→CIFO dedup→CoAP flush, OTA) in firmware/{soldier,queen}/main.c, the mruby bio_contract.rb, and the header-only One-Home libs in firmware/common/ (silken_sha256, lorenz_seed, lora_ccm, silken_crc, queen_attest). Knows the non-obvious gotchas — ECB-restore after CBC, Load_AES_Key before MX_CRYP_Init, RTC DR0..DR19 budget (DR7 freed by FW.54), post-FW.29 StatusByte bit-layo...

23 stars
0 votes
0 copies
0 views
Added 9/20/2026
businessrustgorubynoderailsapibackendsecurity

Works with

cursorapi

Security Analysis

A100/100

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add Alexey-Lukin/silken_net --skill firmware --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Firmware?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Firmware
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/alexey-lukin-firmware/badge)](https://www.skillsdirectory.com/skills/alexey-lukin-firmware)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: firmware
description: "Use when working on the silken_net STM32 firmware — Soldier (sense→TinyML→Lorenz→encrypt→TX, STOP2 loop) and Queen (LoRa RX→CIFO dedup→CoAP flush, OTA) in firmware/{soldier,queen}/main.c, the mruby bio_contract.rb, and the header-only One-Home libs in firmware/common/ (silken_sha256, lorenz_seed, lora_ccm, silken_crc, queen_attest). Knows the non-obvious gotchas — ECB-restore after CBC, Load_AES_Key before MX_CRYP_Init, RTC DR0..DR19 budget (DR7 freed by FW.54), post-FW.29 StatusByte bit-layout, Lorenz continuation vs cold-start, HAL_GetTick frozen in STOP2 (wall-seconds instead — HAL-free arithmetic in wall_time.h, the RTC read in soldier/main.c), vcap = VDDA-mV not EDLC-Vcap, gated CCM vs live ECB — and the host-test parity discipline (make -C firmware/test). The gotcha bodies live in gotchas.md, one generated index line each in the body — open it before touching a peripheral init, the RTC map, the crypto path, the wire format or a gated block. Routes to CLAUDE.md §5 + the 03_01..03_06 canon, does not restate. Examples: \"add a sensor field\", \"change Lorenz params\", \"modify AES / CRYP init\", \"touch RTC-persisted state\", \"why do LoRa decrypts fail after a flush\", \"edit the seed / cold-start crypto\"."
---

# Firmware (Soldier + Queen)

Navigation aid + non-obvious gotchas. The **SSOT is the docs + code below** — this skill
points, it does not restate (so it can't drift). Verify a fact at its home before trusting a summary.

## SSOT Documents — Read These First

| Document | What it covers |
|----------|---------------|
| `CLAUDE.md §1` + `§5` | High-level architecture, AES/key table (post-FW.2 (в)), Lorenz/StatusByte summary — for the exact packet/Status-byte bit-layout trust the canon docs below; OTA wire → gotcha 11 / `03_02 §5` |
| `docs/03_01_Firmware_Lifecycle_and_DMA.md` | Soldier/Queen lifecycle, STOP2 phases, ISR map, **RTC Backup Register Map §2 (canonical DR0..DR19 + magic markers)**, binary packet format §8, mesh-relay + rendezvous ladder §1.9 (CCM-era star-only; single-Queen scale ceiling §1.9.1) |
| `docs/03_02_Queen_Gateway_Firmware.md` | Queen: LoRa RX → CIFO dedup → CoAP flush, OTA broadcast, AES mode transitions |
| `docs/03_03_TinyML_Acoustic_Inference.md` | Audio DMA, TinyML INT8 forward-pass (NOT CMSIS-NN), decision logic, confidence thresholds (DR13/DR14) |
| `docs/03_04_mruby_Lorenz_Attractor.md` | Lorenz constants (§1.2; Z-thresholds §4.1), Float-not-BigDecimal parity, RTC continuation vs cold-start (§2.1), Status-byte packing (§4.4) |
| `docs/03_05_Hardware_Symmetric_Crypto_and_Security.md` | AES modes, key rotation (FW.17), SE05x secure element (baseline SE051C2; SEC.6 + SEC.14 provisioning-only — KEYL stays in Protected Flash; ATECC608B = banner-legacy pattern), IV, QATT wire (§2.2), PQC roadmap |
| `docs/03_06_Factory_Flashing_and_Key_Provisioning.md` | Factory home (split from 03_05 §3.4): HKDF per-device derivation, K_seed, K_ota (FW.23 §4), flashing pipeline + ops-security (SEC.3 §5) |
| `docs/00_07_Action_Plan_Tracker.md` | FW.*/SEC.* task status, open items (canonical home of blockers) |

## Source Files

| File | Role |
|------|------|
| `firmware/soldier/main.c` | Sensor node: sense → TinyML → Lorenz → encrypt → TX (multi-phase STOP2 loop) |
| `firmware/queen/main.c` | Gateway: RX → decrypt → CIFO cache → batch flush via CoAP (CCM-ера gated: blind courier — air-кадр (30B rev2.1) НЕ розшифровується, запис air+1 via `rx_route.h`) |
| `firmware/queen/*.h` | Queen-only pure headers (host-tested): `at_engine`/`coap_pdu`/`sim7070_coap` (FW.3/FW.56 модем-труба + `Sim7070_Read_Csq`), `sim7070_udp` (FW.60 сира CA*-розмова poll-тракту: `Sim7070_Udp_Fetch`, CARECV-заголовок посимвольно; механіка poll'а = `Queen_Poll_Downlink` main.c — канон `03_02 §4а`), `uart_rx_ring`, `ota_window` (FW.52б), `ota_sha_guard` (FW.52 SHA-256 cross-check на Magic Re-Request по закритому OTA-вікну — Queen's ВЛАСНА сторінка 125 [номер збігається з Soldier-івською 125 (K_ota/KEYB, `03_01 §2.3`) — інший чіп, не колізія, але завжди читай «сторінка 125» з іменем чіпа поруч], magic-last; свідомо сиблінг `firmware/common/flash_ota.h`, не reuse), `rx_route` (FW.2 роутер 16/air + запис air+1), `soldier_cmd_queue` (FW.20-Q2), `coap_iv` (SEC.12), `cmd_token` (FW.60/FW.63 — locator of the idempotency token = the LAST field of the CMD envelope; host-pinned in `test_queen_logic.c`; gotcha 1c), `helium_sos` (ARCH.34: 12B SOS-wire byte-parity з `HeliumSosWorker` + тригер + бюджет сліпоти; MAC-шов `Helium_Mac_SendSos` = adapter у `firmware/queen/lorawan_glue/helium_mac.c`; ⚠️ поріг тиші SOS = 2× каденс флашу — заголовок несе лише `#ifndef`-дефолт для host-тестів, справжній каденс підставляє `main.c` з `FLUSH_INTERVAL_MS`+jitter і `_Static_assert`ить нерівність: фіксоване 30 хв було МЕНШЕ за 60-хв каденс і кричало на здоровій Королеві при N ≈ 45–160 (⚖️ 2026-09-10) — той самий клас, що #13(a): pure-заголовок, який дзеркалить константу main.c, мусить мати `#ifndef` і static-assert, не число) |
| `firmware/bio_contracts/bio_contract.rb` | mruby Lorenz attractor (runs on MCU); `calculate_state` is the sole entry-point |
| `firmware/common/*.h` | Shared One-Home libs — header-only except `flash_kv` (`.h` + `.c`) — compiled into BOTH firmware + host tests (kill the mirror-drift pattern): `silken_sha256.h` (SHA-256/HMAC, FIPS/RFC KAT), `lorenz_seed.h` (FW.30 cold-start deriv), `silken_crc.h` (CRC16-CCITT, OTA), `lora_ccm.h` (CCM packet), **`lora_phy.h`** (FW.61 базлайн модуляції raw-LoRa P2P — pure, БЕЗ `Radio`, тож його включає й `cad_sniff.h` у host-тестах; дім номіналів `03_05 §2.1`, модель airtime `tools/firmware/lora_airtime.rb`) + **`lora_phy_apply.h`** (той самий профіль → драйвер: `Lora_Phy_Apply_Tx/Rx`, єдиний шов, ЄДИНИЙ файл у `common/`, що тягне вендорський `radio.h`; ⛔ не зливати з pure-половиною), `tx_defer.h` (FW.10 Cold-TX: `Should_Defer_TX` — freeze-contract на `<` −15°C/4000mV, host-gated One-Home; раніше тест-локальний дубль = false-green; ⚠️ [ARCH.99] Vcap-половина у полі НЕ розрізняє — див. гочу 9), `adc_convert.h` (FW.50 VREFINT-cal ADC→mV; wired: `vcap_voltage = Adc_Vdda_Mv(...)` — VDDA-mV, not EDLC-Vcap), `queen_attest.h` (L1 QATT **v2** signed-batch envelope + 8B health-блок пульсу — ARCH.54; wire home `03_05 §2.2`; residue 1, ct=0 heartbeat легальний), `flash_kv.h`+`fc_hiwater.h`+`ota_antirollback.h` (journal Flash-KV база + FC/OTA-version high-water — SEC.20 anti-rollback ключ 0x15, строго `>`; база винесена з-під фіч-фліп-гейтів: `SEC20_OTA_ANTIROLLBACK_ENABLED 1` (`firmware/soldier/main.c`) тримає декл/mount/**compact** живими завжди (Put32 НЕ auto-компактить)), `fw_report.h` (SEC.20 wire-звіт contract-стану `[semantic:1|reverted:1|hiwater&0x3FFF]` — байти 12..13 legacy / CCM vpd-байт; ⚠️ `FIRMWARE_VERSION_ID` = compile-const C-образу, на дроті її БІЛЬШЕ НЕМА — bytecode-OTA її не міняє), `stack_canary.h` (SEC.21 guard-сів, I-CG: ніколи не нуль; власні `__stack_chk_fail` у обох main.c — Soldier слід DR0[10], Queen reset-only), `mpu_regions.h` (SEC.21 MPU-draft: 3 регіони + SRD-трюк, RW рівно стор. 122-127; гейт `SEC21_MPU_ENABLED` компілиться в hal_check_ccm, trap = bench), `device_event.h` (SEC.21 uplink 0x57 — 2 шари: Шар1 Soldier→Queen ECB-кадр (canary-trip DR0[10]); Шар2 Queen→Rails підписаний L1-конверт `[ver\|ts\|count\|records\|sig]` тег `SLKN-QEVT1` — Королева витягує cleartext і підписує EDSK, Rails verify gateway-origin, LoRa-ключа НЕ торкається; дім `03_05 §2.2а`), `*_selftest.h` + `*_kat_vectors.h` (bench POST) |
| `firmware/test/` | x86 host-based tests — `make -C firmware/test` (host gate; not gcov-instrumented — per-line coverage gaps → best-TU трюк `[[reference_firmware_coverage_gcov_gotcha]]`). **`make -C firmware/test asan`** = ASan+UBSan dynamic memory-safety lane (TEST.5, CI-gating in `firmware_test` — keep it green; canon `04_06 §B.1.1`). New crypto in `common/` ⇒ add a parity test vs OpenSSL, don't re-copy logic into the test file. |
| `firmware/extern/subghz-phy` | Vendored `stm32-mw-subghz-phy` @v1.5.0 (FW.46 Шлях A): `radio_driver/radio.h` = THE Semtech API both main.c compile against (owned stub deleted; both register a **static** `RadioEvents_t` — driver keeps the pointer). `radio.c` NOT compiled until `radio_conf.h` exists (.ioc board-freeze); ⚠️ its `lorawan/` dir is the **LBM radio layer** (SWL2001 support: smtc_ral/ralf, radio_planner, SPI chip drivers) — NOT a MAC stack; the ARCH.34 LoRaMac-node = separate submodule `firmware/extern/stm32-mw-lorawan` @v2.6.2; its `Conf/*_template.h` are CubeMX-fill templates → owned copies live in **`queen/lorawan_glue/`** (EU868-only profile, soft_timer/systime pure-cores, `helium_mac.c` adapter — episode = fresh OTAA join, DevNonce = the ONLY cross-join persist via MIB_NVM_CTXS→flash_kv 0x30). Host-smoke of the REAL MAC on a stub radio: `make -C firmware/test helium_mac_smoke` — full OTAA join+uplink cycle vs an in-test mock-LNS (crypto-valid JoinAccept on the zero-key se-identity; server-side MIC + FRM parity with LNS-derived session keys; deadline = the real 20s blind budget at SF12-TOA) + a crypto-valid 23B JoinRequest + DevNonce monotonicity/KV-reboot. The mock needs `-DAES_DEC_PREKEYED` (smoke-target-only — the server ENCRYPTS JoinAccept with AES-decrypt; mirrored in `firmware/.clangd`). ⚠️ `Helium_Mac_Bind_Nvm` keeps the pointer forever — bind only a static/file-scope FlashKv (ASan stack-use-after-scope class). ⚠️ The recipe links **`-lm`**: `RegionCommon.c` calls `floor()`, and the **coverage lane's `-O0`** (`make coverage`) does NOT inline it as a builtin the way `-O1` (asan) / `-O2` (normal) do → a green local `helium_mac_smoke` + `asan` still red-CIs on coverage without it (the class: a vendored-math TU needs explicit `-lm`; `make coverage` is the only lane that catches it). ARM targets: `lorawan_mac_check` (glue+MAC) is a CMake target NO CI step builds — and built by hand 2026-09-19 it FAILS (`helium_mac.c`: `stm32wlxx_hal_conf.h` not found → `00_07` FW.65); `hal_check_ccm` (CI, and locally — gotcha 7.4) compiles the gated Queen KV-mount block (ARCH34_HELIUM_ENABLED=1). The submodule is OUR FORK `Alexey-Lukin/stm32-mw-lorawan` @v2.6.2-silken.1 — v2.6.2 + one fix: `RegionCommonComputeSymbolTimeLoRa` SF11/SF12 signed-overflow (upstream Semtech master has the same hole; UBSan found it, upstream-PR = `00_07` ARCH.34 👤). Bumping the submodule → re-check that fix survives. Include-path lives in CMake hal-lane + `firmware/.clangd` (change one → sync the other) |

> Line counts drift every commit — don't hardcode them (see `[[feedback_no_volatile_counts]]`); `wc -l` if you need a number.

## Gotchas Not Obvious From Docs

**Bodies live in [`gotchas.md`](gotchas.md) — open it before you touch a peripheral init, the RTC map, the crypto path, the wire format, a gated block or the lint lane.** One generated line per gotcha below: the line is the CARRIER, meant to stop you mid-action; the mechanism and the bounds are in the companion. Numbering is append-only (`1b` · `1c` are items of their own) — cite `firmware #N`.

<!-- FIRMWARE-GOTCHAS-INDEX:AUTO — generated from gotchas.md by `ruby scripts/guard_craft_index.rb --write`; edit rules THERE, never here -->

1. Shared peripheral, per-operation reconfig: restore the baseline — and make sure a baseline EXISTS
1b. Queen re-resolves the CoAP server IP after N≥3 consecutive flush-fails, so an A-record flip is picked up without an IWDG reboot
1c. Retransmit is UPLINK-only — the downlink poll has none, so a lost 2.05 is recovered only by the `cmd=` echo cursor, never by a CoAP retry (FW.63)
2. RTC registers are nearly all spoken-for — but allocated ≠ optimally packed
3. `Load_AES_Key()` must run BEFORE `MX_CRYP_Init()` — reversed, CRYP silently uses a zeroed key
4. Cold-TX deferral: at low temperature the Soldier skips TX entirely, so never assume every wake cycle emits a packet
5. StatusByte layout is post-FW.29 — `[PanicFlag:1 | Status:2 | GrowthPoints:5]`, and status 3 means vm_error, never tamper
6. Lorenz state on boot is a warm continuation from DR16–18 only when DR19 holds the magic AND all three values are finite, otherwise a cold start derived from `K_seed`
7. CCM is gated, ECB is live — WL CCM API is TWO-PHASE, and the CCM era is TWO-KEY
8. `HAL_GetTick()` is frozen in STOP2 — a tick delta measures active time only, never wall time, so use wall-seconds
9. `vcap_voltage` is honest mV of VDDA, NOT the EDLC Vcap — the rail says nothing about stored energy, so all four thresholds on it are degenerate
10. `BIO_STATUS_VM_ERROR = 0x60`, not 0xFF — it must survive the panic-bit mask (`& ~PANIC_FLAG_BIT`) as status 3 with zero growth points
11. OTA wire has two layers with different headers — LoRa Queen→Soldier and CoAP Rails→Queen — and a length is never guessed from padding
12. cppcheck version-skew: a green local lint proves NOTHING about CI
13. Enabling compile-coverage of a gated block = wire ALL its board-freeze deps FIRST; only the ARM `hal_check_ccm` lane sees the gated branch, so build it locally (`firmware/.toolchain/`, gotcha 7.4) before pushing, or each miss is a separate red CI push
14. The audio window is guarded BEFORE the HAL, and the vendored HAL is the reason

<!-- /FIRMWARE-GOTCHAS-INDEX -->

## Common Tasks

- **Add sensor field**: Soldier Phase 1 ADC → pack in `lora_payload[]` → Queen `Process_And_Cache_Data` → `Flush_Cache_To_Rails` → Rails `TelemetryUnpackerService` unpack string → host tests. Check the budgets first: a wire byte → a row in the `03_05 §2.1` wire-budget ledger before it is promised (headroom after rev2.1 = 0); RTC-persisted state → gotcha 2.
- **Change Lorenz params / `bio_contract.rb`**: edit `bio_contract.rb` AND `app/services/silken_net/attractor.rb` → run parity tests (must stay bitwise-identical, Float IEEE-754 both sides). **Three hidden gates a subset-run misses** (the first two tripped in E.63 + E.64): (1) regenerate `lorenz_bytecode.h` (`tools/firmware/gen_bytecode.sh`) — the **FW.46 sha256 stamp-gate goes red if it's stale**; (2) a signature change → grep **`spec/` too** (not just app/lib — once missed 6 integration-spec callers) + run the **FULL `bin/rspec`**, never a subset, before pushing a contract/DCI change; (3) the SHA-pins `lorenz_core` / `metabolic_gp_core` in `lib/canonical_block_pins.yml` — `bin/rails docs:check_refs` stays red until the mirrors listed there are reconciled and `rake docs:repin` is run.
- **Change seed/cold-start crypto**: edit `firmware/common/lorenz_seed.h` / `silken_sha256.h` ONCE (shared) → `make -C firmware/test seed_derivation` re-proves parity vs OpenSSL + backend `SeedDerivation`. Never fork the math into the test file.
- **Modify AES**: touch `MX_CRYP_Init()` in BOTH files, update `Load_AES_Key()`/`Load_Broadcast_Key()`, `Restore_ECB_Mode()`, host tests — and preserve the two-key scoping contract (gotcha 7.3; guarded by `test_ccm.c::test_two_key_scoping_contract` + KEYB-load tests in `test_soldier_logic.c`). On a bench, silicon is attested by the `CCM_SELFTEST` build + `firmware/scripts/bench/02_selftest_attest.py` (RUNBOOK §2.1–2.2) — it catches the `CRYP_DATATYPE_32B` word-swap class invisible to host mocks; `make -C firmware/test selftest sym_selftest` only proves the self-test logic + KAT vectors on the OpenSSL mock. New factory key slot? Mirror it in `FactoryFlashing::CommandBuilder` + `03_06 §2` (page 124 = per-device identity, page 125 = cluster membership KOTA/KEYB).
- **Touch RTC-persisted state**: update the `03_01 §2` canonical table FIRST (SSOT), add `isfinite()`/magic/range restore guards, then ≥3 host tests (cold-boot / warm-roundtrip / corruption-fallback).

Attribution

Alexey-LukinAlexey-Lukin
View sourceMore from Alexey-Lukin →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Solution Architect

Designs system architecture, component specifications, and technical integration strategy. Use when: designing solutions, system architecture, technology stack, or integration approaches.

192 votes

Akorchak:Venture Assessment

Generate a comprehensive VC investment assessment report for a company

72 votes

Just Fucking Cancel

Find and cancel unwanted subscriptions by analyzing bank transactions. Detects recurring charges, calculates annual waste, and helps you cancel with direct URLs and browser automation. Use when: 'cancel subscriptions', 'audit subscriptions', 'find recurring charges', 'what am I paying for', 'save money', 'subscription cleanup', 'stop wasting money'. Supports CSV import (Apple Card, Chase, Amex, Citi, Bank of America, Capital One, Mint, Copilot) OR Plaid API for automatic transaction pull. Out...

6511 votes

Stock Analysis

Analyze stocks and cryptocurrencies using Yahoo Finance data. Supports portfolio management (create, add, remove assets), crypto analysis (Top 20 by market cap), and periodic performance reports (daily/weekly/monthly/quarterly/yearly). 8 analysis dimensions for stocks, 3 for crypto. Use for stock analysis, portfolio tracking, earnings reactions, or crypto monitoring.

6511 votes

Telegram Compose

Compose rich, readable Telegram messages using HTML formatting via direct Telegram API. Use when: (1) Sending any Telegram message beyond a simple one-line reply, (2) Creating structured messages with sections, lists, or status updates, (3) Need formatting unavailable via Clawdbot's Markdown conversion (underline, spoilers, expandable blockquotes, user mentions by ID), (4) Sending alerts, reports, summaries, or notifications to Telegram, (5) Want professional, scannable message formatting wit...

6511 votes
View all in business →