Telemetry Pipeline
SkillDev toolsUse when working on the silken_net telemetry / Proof-of-Growth pipeline, the uplink→verification→minting flow (CoAP intake → UnpackTelemetryWorker / TelemetryUnpackerService → IoTeX verify → Chainlink oracle → mint), the Sidekiq strict-priority queues, TelemetryLog (RANGE-partitioned, KENOSIS, validations live in valid_sensor_data?, not the model), and the dual-computation integrity (server Float Lorenz ≡ firmware mruby). Knows the gotchas, DID=0 in a batch is DEAD (ARCH.54: Queen pulse rides the signed QATT-v2 header → enqueue_envelope_health, both eras drop DID=0), oracle_status_*? enum methods, strict queue drain (uplink fully before alerts), partition-pruning One-Home (TelemetryLog.partition_pruned, NOT find_with_partition_pruning, which is BlockchainTransaction's). Routes to CLAUDE.md §5/§6 + the 05_02 canon, does not restate. Examples: \"add a telemetry field\", \"change minting logic / guards\", \"why is an alert delayed\", \"decode the uplink packet\", \"why does server Z differ from device Z\".
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Telemetry Pipeline skill
What this skill tells your AI
The instructions your AI receives, as published by alexey-lukin/silken_net in .claude/skills/telemetry-pipeline/SKILL.md and read by ahel’s review.
SSOT Documents — Read These First
| Document | What it covers |
|---|---|
CLAUDE.md §1 | Proof of Growth pipeline — full A→D flow (sense→…→mint SCC) |
CLAUDE.md §5 | Sidekiq strict-priority queues + Lorenz/StatusByte + AES invariants |
CLAUDE.md §6 | Telemetry cross-domain gotchas (oracle_status prefix · KENOSIS · partitions) |
docs/05_02_Proof_of_Growth_Pipeline.md | Exact worker ordering with queue assignments |
docs/05_03_Tokenomics_SCC_and_SFC.md | Growth points, SCC minting (slashing → 05_05) |
docs/03_05_Hardware_Symmetric_Crypto_and_Security.md §3 | AES decrypt chain, key management |
Gotchas Not Obvious From Docs
-
DID
0x00000000in a batch is DEAD (ARCH.54, 2026-07-03) — the old Queen-Sentinel pseudo-tree is dropped on BOTH paths (ECB and CCM): the pulse rides the SIGNED QATT-v2 envelope header (8B health block,firmware/common/queen_attest.h) →UnpackTelemetryWorker#enqueue_envelope_health→GatewayTelemetryWorker. Never re-add gateway metrics as a fake tree — it eats a CIFO slot, breaks the CCM stride, and health without a valid Ed25519 must not exist (masking-attack). Canon:03_02 §7+06_08 §1.3. ⊕ [FW.59, 2026-09-08] The 8B block'sflagsbyte is NOT homogeneous, so never read it as a flat bitmask: bits 0..3 are era/drop flags, bit4 is BOOKED (SEC.21 canary, enforced by a_Static_assert— do not take it), and bits 5..7 carry the reset cause (GatewayTelemetryLog#reset_cause). 🔴 Code0there means NOT REPORTED, never «cold start» — every pulse row older than FW.59 carries zeros, so reading0as a cause back-dates a verdict onto the whole history. Layout homefirmware/common/queen_attest.h, codesfirmware/common/reset_cause.h, prose03_02 §7.1. -
oracle_status prefix — call
log.oracle_status_fulfilled?notlog.oracle_status == "fulfilled". String-backed enum withoracle_status_prefix. -
Dual computation — server Lorenz (Float) must match firmware mruby (Float). Was BigDecimal before FW.7 — old
to_dcode is a bug now. -
Queue drain is strict —
uplink(#1) drains COMPLETELY beforealerts(#2). Telemetry flood blocks alerts. By design. -
Validations removed from TelemetryLog — KENOSIS TITAN. Check is in
TelemetryUnpackerService.valid_sensor_data?. Don't add validations back to model. -
Partition-aware lookups —
TelemetryLogis RANGE-partitioned bycreated_at(monthly leaves; +1 every month, no drop/detach mechanism exists YET). ⛔ Рядкового retention тут НЕ БУДЕ — це присуд, не прогалина (⚖️ 2026-08-21,00_07ARCH.59): ретеншн робить ВИКЛЮЧНО дроп місячних партицій, будь-якийdelete_allнадtelemetry_logs— регресія, і її ловитьspec/quality/telemetry_retention_home_spec.rb. Підстава — прилад: тракт архіву вже очікує саме дропу й має для нього чесний стан (TelemetryArchiveBatch.retention_expired= «листя менше, бо партиції дропнуто — НЕ tamper»), тож ДРУГИЙ механізм зникнення рядків зробив би цей статус неоднозначним. ⚠️ Знятийcleanup_old_logs!був НЕДОСЯЖНИЙ (єдиний викликач — мертвийSidekiq::Batch-колбек), і саме тому небезпечний: покупка Pro-ліцензії озброїла б його мовчки, без окремого рішення. ⚠️telemetry_logs_defaultis pruned or not depending on the SHAPE of the predicate, and this skill used to say flatly "never" — re-measured 2026-08-07: a closed window (created_at: t...t+1) prunes to exactly 1 leaf, so the default goes too; an open lower bound (>= cutoff) and an unbounded query cannot prune it, and there the default is a permanent extra probe. Say which form you mean. The One-Home set is three methods over two of the three models — pick by CARDINALITY, not by habit:TelemetryLog.partition_pruned(created_at_iso, metric_caller:)(chainable scope) ·BlockchainTransaction.find_with_partition_pruning(id, created_at, metric_caller:)(ONE row) ·BlockchainTransaction.where_ids_pruned(ids, span, metric_caller:)(a SET of known ids —span= thecreated_atof those same rows, so the row set is unchanged; a planner hint, never a filter). BothBlockchainTransactionforms now count their degraded path (silkennet_blockchain_transaction_unpruned_lookups_total) — the old silent-fallback asymmetry is closed.GatewayTelemetryLoghas no helper, deliberately: zero id-lookups exist on it, so one would be a lever with no puller. 🔴 Never hand-roll the narrowing — exact equality oncreated_atmisses by construction (ISO-8601 carries seconds, the column microseconds) and that form shipped three times; on the mint path the miss is silent (return unless log→ the job succeeds having done nothing). ⛔ But astatus-scan is NOT this class and a bound there is HARMFUL (ARCH.52: reset-to-pending keeps an OLDcreated_at, so a lower bound orphans stranded funds; the lever is a partial index). Rule of thumb: a window prunes a lookup for a KNOWN row; an index prunes a set of unknown size. The invariant now has a carrier —spec/quality/partition_key_discipline_spec.rb(declaration required per.reloadand per id-lookup). Canon:04_01⚡ PARTITION PRUNING INVARIANT [S6.16]. -
«Wire = вхід GP» contract (E.63 (г), wire-rev2.1) — the CCM frame carries BOTH dT fields: raw (bytes 12..13, diagnostics/server-EMA) and
ema_delta_t_s(bytes 20..21) = the EXACT numbermetabolic_healthconsumed on the device →check_metabolic_divergence!recomputes GP statelessly viaAttractor.expected_homeostasis_gp(ema)(byte-identical mirror ofbio_contract.rb§4.3 — edit the formula/thresholds THERE first, mirror second, regenlorenz_bytecode.h). The branch is observational (warn+metric) until the bench calibratesDELTA_T_FAST_S/DELTA_T_SLOW_S;ema_delta_t_sis transient (stripped pre-persist, likelorenz_temperature_c/device_z). ECB frames carry no ema → branch honestly skips. Canon:03_04 §4.3+03_01 §13.6. -
firmware_version_id= wire-ЗВІТ, не FK (SEC.20, 2026-07-12) — post-SEC.20 семантика[semantic:1|reverted:1|contract_id&0x3FFF](дзеркалоfirmware/common/fw_report.h): читай черезTelemetryLog#firmware_report_semantic?/reverted?/contract_id(id ПО МОДУЛЮ 14 біт — НЕ join і не пряме порівняння зBioContractFirmware.id); legacy-кадри (без semantic-біта) несуть C-image константу — contract-версії НЕ мають.reverted?→EwsAlert firmware_reverted(термінальний: re-issue лише версією > спаленої — 03_06 §4 bump-інваріант). -
TelemetryLog тепер несе MRV-lineage сліди (ARCH.12/E.60, 2026-07-19) — mint-інтенти отримують детерміновані вікна вимірів (
Walletwatermark-курсор →telemetry_window_*на tx), а pin-воркер стемпитьtelemetry_logs.{archive_root, merkle_leaf}(E.60 Фаза 1б). Перший AR-колбек моделі:before_updateseal-guard — мутаціяz_value/bio_status/created_at/tree_idстемпнутого рядка = raise (KENOSIS недоторканий: intake = insert_all, колбек не стріляє; oracle_status/verified_by_iotex — не leaf-поля, вільні). Leaf-формула One-Home =05_02 §E.60(Mrv::TelemetryLeaf, LEAF_VERSION). Не додавай у leaf-payload нове поле безLEAF_VERSION-bump. -
Device-event 0x57 = ОКРЕМИЙ L1-канал, не телеметрія (SEC.21, 2026-07-12) — рідкісні security-події (canary-trip) НЕ їдуть телеметрійним трактом: окремий CoAP
PUT device/event/<uid>→DeviceEventWorker(неUnpackTelemetryWorker). Королева підписує cleartext-конверт власним EDSK (тегSLKN-QEVT1, окремий від QATT2) → worker verify gateway-origin (HardwareKey.ed25519_public_key_hex, як QATT-батч), Rails LoRa-ключа НЕ торкається. Не плутай з CCM blind-courier телеметрії (там per-DID decrypt на Rails); тут — L1-підпис Королеви. Trust L1-observational, НІКОЛИ не money-path. Дім03_05 §2.2а+03_02 §7а. -
🔴 Детекція OTA-mismatch гейтована колонкою, якої доти не писав НІХТО — тож гілка ніколи не виконувалась, і оживить її не телеметрія, а фікс форми.
TelemetryUnpackerService#latest_tree_firmware_idбереBioContractFirmware.active.where(target_hardware_type: "Tree"), аcheck_firmware_mismatch!виходить на власнийreturn if latest_id.nil?. Писальників тієї колонки вapp/було нуль (форма завантаження слала ключ без колонки), тобто при суто-nil популяції детекція мовчить за побудовою, а не через дані. Наслідок для читача цього тракту: щойно з'явиться перший типізований реліз, кожен аплінк із розбіжним contract-id почне ставити деревамfirmware_update_status: :fw_pending— це зміна поведінки гарячого шляху, спричинена сусіднім доменом. Рефлекс: перед тим як довіритись будь-якій гілці, гейтованій значенням колонки, перелічи ПИСАЛЬНИКІВ, а не читачів — колонка, яку ніхто не пише, робить гілку декоративною, і читацький бік при цьому виглядає справним. ✅ ПРИСУД 2026-08-14 (ARCH.85, §🗄️): гілка лишається СПОСТЕРЕЖНОЮ, не дієвою — вона пишеlogger.infoпро розбіжність іfirmware_update_statusНЕ міняє. Дієвийupdate_allзнято, не закоментовано. Підстава — blast-radius першого прогону: тракт не біг жодного разу, тож перший запуск стався б одразу в полі, на гарячому шляху, і при хибній деривації позначив биfw_pendingвесь флот, а ретрансміту в цього стану немає (FW.63). ⚠️ Прапорця-перемикача свідомо НЕМА (забутий прапорець = тихо вимкнений захист, прецедентINF.11), тож оживлення = зняти один рядок ПІСЛЯ того, як лічильник покаже правдоподібні числа на живому флоті. ⊕ Заразом закрито сусідній зомбі:deploy_globally!не гасив БЕЗТИПНИХ предків (where(col: X)це SQL= X, а NULL не дорівнює нічому) — скілbackend#44. -
🔴
acoustic_eventsзмінив wire-семантику (ARCH.102, 2026-08-16): тепер це «детекції від останнього УСПІШНОГО uplink'а» — а доти на дроті було завжди 0 або 1, і бекендні пороги писались під семантику «подій за вікно», якої прошивка не мала. Фаза 2 Солдата знімала І ОБНУЛЯЛА лічильник на кожному проходіwhile(1), а три інкременти взаємовиключні (if/else ifпо зоні впевненості й класу) → максимум +1 на пробудження; тож обидва порогиAlertDispatchService—insect_epidemic(> 50) іseismic_anomaly(>= 200) — були недосяжні з реального заліза і стріляли лише на наших-таки сідах/HIL-профілях. Після фіксу лічильник споживає ЛИШЕ успішна передача телеметрії (віднімання знімка, не обнулення) — детекції deferred-TX-циклів (мороз) і grace-hello більше не зникають, незʼїдений залишок переживає STOP2 у DR0 — тож багатоциклове накопичення тепер легальний wire-вхід (0xFE лишається time-uncertain-сентинелом, який unpacker нейтралізує ДО DCI). 🔴 Обидві вердикт-гілки на цьому лічильнику ЗНЯТО тим самим присудом, і підстава пережила фікс: поріг став досяжним, а вимірювача так і немає — класу «комаха» в TinyML нема взагалі, сейсмічного каналу теж, лічильник рахує кавітацію та пилку. Тобто «полагодити семантику» і «зробити вердикт чесним» — різні роботи, і перша другої не дає. Живих споживачів цього поля лишилось два, обидва справжні: DCI-парність σ (03_04) і panic-канал пилки. ⛔ Не додавай нової гілки на це поле без відповіді на «а звідки ти це знаєш» →00_07ARCH.102 +04_02 §2. -
🔴
telemetry_logs.sap_flowне пише НІХТО — колонки нема в жодному wire-форматі (PAYLOAD_FORMAT,CCM_SENSOR_PAYLOAD_FORMAT), писальників уapp/нуль — а читачі живі, і найгостріший тихо вимикає антифрод. Виміряний ланцюг, яким клас знайдено: fraud-базлайнInsightGeneratorServiceбравAVG(sap_flow)по суцільних NULL →nil→.to_f→0.0→detect_fraud?коротко замикався наbaseline[:sap].zero?, тобто sap+temp-гілка антифроду в проді не могла спрацювати ВЗАГАЛІ; зеленою її тримали лише фабрики/сіди, що виставляють колонку руками (клас «фікстура виготовляє вимір»,TEST.12/04_06 §B.2BP #14). Це друге живе втілення рефлексу з #11: гілку, гейтовану значенням колонки, спершу звіряй із переліком ПИСАЛЬНИКІВ, не читачів. -
🔴 Enqueue телеметрії мусить нести момент ПРИЙОМУ — інакше доба cold-derive Лоренца тихо з'їжджає на добу ОБРОБКИ [ARCH.41, 2026-08-28].
UnpackTelemetryWorker#performмає ЧЕТВЕРТИЙ аргументreceived_at_iso, який їде далі якTelemetryUnpackerService.call(received_at:)і читається One-Home-методомderivation_epoch_day. ⚠️ Обидві опції, які здаються очевидними, ХИБНІ:Time.nowрухається зі спробою, аtelemetry_log.created_atставиться при ВСТАВЦІ, тобто на Sidekiq-ретраї він такий самий новий. Єдина величина тракту, стабільна між спробами, — момент прийому, зафіксований інтейком і серіалізований у job-аргументи. Ціна промаху: ретрай через межу півночі UTC дає іншийepoch_day→ інший (x₀,y₀,z₀) → категоричний DCI-мисматч на ЧЕСНОМУ дереві, і ловити його НІКОМУ:try_time_sync_recovery(ARCH.41-A) гейтований!cold_start_flag, тобто страхувальна сітка структурно відсутня рівно на cold-start, де деривація й відбувається;-B/-Cстережуть НЕсинхронізований пристрій, а тут час пристрою правильний. 🔒 Аргумент ОПЦІОНАЛЬНИЙ за побудовою (nil= «прийом зараз», легально для bench/HIL/спек), тож його ВТРАТА на прод-сайті нічого видимого не ламає — це тримає гейтspec/quality/telemetry_received_at_propagation_spec.rbіз ліхтарем периметра, що червоніє на НОВОМУ продовому enqueuer'і. ⛔ Додаєш enqueue-сайт — передавайTime.current.utc.iso8601четвертим;lib/silken_net/load_test/**свідомо поза периметром (bench не моделює прийом). ✅ Стан переміряно 2026-08-17, і він змінився двічі: той fraud-читач ЗНЯТО (нуль хітів наAVG(sap_flow)/baseline[:sap]), а04_01 §2тепер несе DEAD-маркер, якого тут доти «не було». 🔴 Але живий читач лишився РІВНО ОДИН, і попередній свіп його не бачив:OracleVisionsController#calculate_expected_yieldбере колонку через мапуTelemetryLog.latest_per_tree, тожnext if sap_index.nil?спрацьовує на КОЖНОМУ дереві — покриття прогнозу структурно0 з N, а «Projected 24h Emission» є константою0.0. Урок про сам свіп, ширший за випадок: перелічувати читачів за ІМЕНЕМ колонки недостатньо — сайт, що заходить за спільним ВХОДОМ (мапаtree_id → log,pluck,select), імені моделі поруч не має. Читача лишено свідомо з названою умовою оживлення (полеsap_flowу wire-форматі), бо число не бреше — покриття їде поруч →00_07ARCH.102/ARCH.103. -
🫁 Soldier-pulse НЕ є окремим кадром і не потребує гілки в розпакувальнику [SILENCE-1, ⚖️ 2026-09-04]. Кадр «я тут, але нічого не міряв» — це той самий 30B CCM-пакет із
delta_t = DELTA_T_UNKNOWN_S, що дає на дроті паруstatus = 0, GP = 0, якої у ВИМІРЯНОГО гомеостазу не буває (той починається зGP_HOMEO_MIN) — тобто регістр оголошений даними, без нового опкоду, довжини чи прапорця. Присуд обрано виміром: найближчий вільний розмір (17 Б проти 30) виграє лише ≈61 мс airtime ≈ 8 мДж ≈ 1.6 % добового балансу, тоді як коштував би гілки вQueen_Rx_Classify(він розрізняє кадри СУТО за довжиною: 16 → ECB, 30 → CCM, решта → тихий дроп), нового опкоду, вектора й гілки декрипту. ⛔ Тож не додавайpulse?-предиката й не роздвоюй шлях: будь-яка гілка «це pulse» відтворює той самий поділ на рівні, де його немає в даних. Що ВАРТО тримати — ТРИ піни: pulse штампуєlast_seen_at(інакше він не розвʼязує конфаунд «мовчазне здоровʼя ↔ мертвий вузол», задля якого існує) · НЕ дає балів (інакше вузол отримує гроші за відмову міряти — рівно цінаBASELINE_DELTA_T_S) · і НЕ кричить fraud. 🔴 Третій дописано 2026-09-06, і саме його бракування тримало ЖИВИЙ дефект:check_metabolic_divergence!вимагавGP ∈ 5..31при гомеостазі, тобто читав ОГОЛОШЕНУ паруstatus = 0, GP = 0як порушення смуги й інкрементувавTELEMETRY_FRAUD_DETECTED_TOTALна ЧЕСНІЙ відмові вузла — при тому, що прошивка власним коментарем каже: бекенд розрізняє «зрив» від «не міряли» за СТАТУСОМ, не за балами. ⚠️ Дві половини ОДНОГО присуду розійшлись тихо — ТОЧНА гілка (expected_homeostasis_gp(0)→ 0) сентинел знала, СТРУКТУРНА ні. Ціна щоденна:Wall_Seconds_Now()віддає 0 до LSE/RTC bring-up (FW.49), тож на кремнії сентинел іде щоцикла — вічно-червоний fraud-канал є безмовним (S2.4-закон). 🔑 І урок про сам пін: він був ЗЕЛЕНИЙ на прикладі, який САМЕ ЦЕЙ кадр і шле — міряв живість і бали, а мовчання третього каналу не міряв узагалі. ⚠️ Перша спроба це виправити виміряла МОК: файловийbeforeтієї спеки пінитьcalculate_z_from_stateу[0.5, …], тобтоserver_zпоза смугою, і Z-канал кричав ЗАКОННО; лік — повернути z у смугу локально, а не «полагодити» код під фікстуру. Дім —06_08 §1.3; сусідній писач-інваріант — скілbackend#83. -
⛔ Z у продові читає РІВНО ОДИН споживач —
check_z_divergence!(DCI). Не заводити зz_value/Attractor-предикатів жодного вердикту про ЗДОРОВʼЯ [E.64 (A), ⚖️ 2026-09-05]. Лоренц є печаткою обчислювальної цілісності: те саме обчислення повторюється на пристрої й на сервері з того самого секретного зерна й мусить збігтись категорично. Про фізіологію він не свідчить ЗА ПОБУДОВОЮ — детермінована функція від входів, які верифікатор і так має в plaintext, тож за data-processing inequality не додає інформації понад них (05_05 §8.1). 🔴 І це не теорія — так уже сталось ТРИЧІ, на трьох рівнях агрегації, щоразу з ВИМІРЯНОЮ ціною: (1) серверна гілкаAttractor.homeostatic?→severe_droughtспрацьовувала на ЧЕСНИХ деревах у 1.4 % (MAX-бік, тепла погода); (2) кластернаentropy_anomalyдавала «здорову» смугу 0.908 на лісі з НУЛЬОВОЮ біологічною різницею (⚖️ 2026-09-05 тракт знято ЦІЛКОМ — писач, сервіс, cron, gauge, Grafana й сама колонкаclusters.entropy_score; enum-значення й локаль-ключ лишені історичними заради рендеру архівних рядків); (3) найдорожча й знайдена ОСТАННЬОЮ —avg_zяк ФІЧА RandomForest уInsightGeneratorService#calculate_stress_index(знято 2026-09-05, дім →00_07E.52): через ML це не мʼякше, а ГІРШЕ, бо евристична гілка має стелю0.6 < 0.83, аpredict_probaне має жодної — тоді якstress_indexіде ПРЯМО вBlockchainBurningService(slashUpTo), Celo-виплату й страховий Trigger-1. ⛔ Тож заборона накриває не лише предикати, а й НАВЧАННЯ:avg_zу фіча-векторі є тим самим вердиктом, лише схованим у вагах, де його вже не видно ані грепом, ані ревʼю. Спільна причина всіх трьох — розкид Z між деревами породжений їхнімиK_seed, які ми ПРИЗНАЧИЛИ, а не мікросередовищем. 🔑 Дискримінатор, що ловить наступний випадок: питай не «чи прилад справний», а «про ЧИЙ предмет він свідчить» — про дерево чи про наше власне слово, сказане дереву. ⊕ Легальний біо-гейт лишається один — ПРИСТРІЙНИЙbio_status(він теж вироджений:stress=z < 2.0недосяжний за ρ-clamp, тож перил посухи сьогодні не має авто-писача, і це оголошено в00_04 §2). Здоровʼя мусить прийти з ПРЯМИХ вимірювачів (вологість · sap-flow · VPD · акустика) — їх у залізі ще немає, і доти чесна відповідь: «ніхто не міряв». -
📡
TelemetryUnpackerService#performПОВЕРТАЄSummary, а трансляція в UI стоїть ПІСЛЯ нього — і обидві половини несучі [UI.16, 2026-09-06]. ДотиUnpackTelemetryWorkerкликавbroadcast_to_matrixперед розпакуванням і славbinary_data.unpack1("H*")— сирий hex конверта, під заголовком колонки, що це прямо називав; лісгосп бачив шістнадцятковий дамп на клієнт-фейсній сторінці в головній навігації. 🔴 Дорожчою була не семантика, а ПОЛОЖЕННЯ: зовнішнійrescueуperformвиняток не ковтає, а ПЕРЕКИДАЄ його заради Sidekiq-retry, тож стабільно падаюча ПРИКРАСА робила батч таким, що ніколи не розпакується (ретраї вичерпуються → dead set, черга №1, найдорожчі дані платформи) — саме тому [UI.4] мусив рятувати викликrescue-ізоляцією. Перенесення знімає hazard СТРУКТУРНО: після коміту рядків збій рендера фізично не має чому завадити. ⛔rescueпри цьому НЕ знімати — його предмет ЗВУЗИВСЯ (не дати збою кабелю зіпсуватиCOAP_PACKETS_RECEIVED_TOTAL{status="success"}і фіналізацію QATT-nonce), а не зник; без нього повертається пере-обробка вже закоміченого конверта. 🔑Summaryродиться в сервісі, бо лише він знає, скільки записів ЛЯГЛО, іdroppedтам виводиться (records − committed), а не лічиться на місцях відкидання: тих шість, вони ростуть, і будь-який перелік старів би лише в бік ЗАНИЖЕННЯ — тобто зведення тихо казало б «усе гаразд». Єдина точка накопичення —commit_telemetry, впритул доTELEMETRY_PROCESSED_TOTAL(тотожна семантика). ⚠️ Порожній конверт (empty-flush heartbeat) стрічку не смикає: пульс Королеви має власний дім (гоча 1). ⛔ BACKFILL зведень — присуд «НЕ БУДУВАТИ»: «флаш» не є сутністю в БД, а реконструкція поqueen_uid+ секунді розриває частину батчів навпіл, тобто HUD брехав би про кількість флашів; порожнеча лікується ВИМІРОМ у плейсхолдері, не відтворенням стрічки. ⚠️ І пам'ятай про стаби: будь-яка спека, що мокаєTelemetryUnpackerService.call, мусить віддаватиSummary— голийreceive(:call)даєnil, броадкаст падає вrescue, і приклади про скоуп стріму лишаються зелені на порожній множині. -
🌲
bin/forest_simulatorтепер РАХУЄbio_status, і DCI на демо-прогонах перестала бути завжди-червоною [E.64, 2026-09-06]. Доти обидва поля StatusByte бралисяrand(), тобто сторона, яку DCI звіряє з серверним Z, ГЕНЕРУВАЛАСЬ — і перший multi-node прогін на canopy запалив критичнийTelemetry fraud detected, істинно-позитивний: «шахраєм» був наш власний симулятор. ⚠️randламав ДВІ звірки, не одну:growth_points = rand(0..31)окремо порушувавcheck_metabolic_divergence!(homeostasis → GP ∈ 5..31,stress → GP == 1). Модель вузла живе вHil::SoldierNode(сусідHil::QueenSimulator; скрипт — тонкий викликач, бо спек уbin/не буває): власний Lorenz-ланцюг, cold-start ізK_seedчерезSeedDerivationтим самим виразом доби, що йderivation_epoch_day, далі продовження з ВЛАСНОГО хвоста. 🔑 Ланцюг власний СВІДОМО: симулятор, що читає серверний хвіст ізtelemetry_logs, зелений за побудовою — та сама беззмістовність, лише протилежного знаку доrand. ⚠️ Стеля названа: це НЕ доказ незалежності обчислень (обидві сторони крутятьSilkenNet::Attractor) — доводиться ТРАКТ; байт-парність тримають sweep проти СПРАВЖНЬОГО контракту (tools/firmware/contract_runner.rb, підпроцес) і FW.55. ⛔ Той міст у симулятор не переноситься:/firmwareі/toolsне їдуть у Docker-образ ([OPS.10]), а на canopy симулятор біжить у job-контейнері. 🔴 І живий слот одразу знайшов дефект, якого аналіз не бачив: ланцюг двійника живе в ПАМʼЯТІ ПРОЦЕСУ, а RTC справжнього Солдата переживає перезавантаження. Тож ПЕРЕЗАПУСК симулятора — артефакт емуляції, не подія пристрою: вузол cold-стартував ізK_seed, тоді як сервер мав хвіст попереднього прогону й продовжував ТЕПЛО → категоричний DCI-mismatch на ЧЕСНОМУ дереві. Виміряно на canopy:time_unsynced_fallback = 2на 147 рядків, і кожен такий кадр ще й ставивTimeSyncDownlinkWorker, який ретраївся в Королеву, якої там немає за конструкцією, аж у DeadSet. 🔑 Розрізнення несуче й не інтуїтивне: читати серверний хвіст на КОЖНОМУ пакеті — циркулярність (зелене за побудовою); читати його ОДИН РАЗ на процес — відновлення памʼяті двійника, бо серверний хвіст і Є записом того самого RTC. Далі ланцюг знову незалежний. ⚠️ Стеля названа: перший кадр на дерево після рестарту продовження НЕ доводить — вакуумно, але чесно, тоді як доти було хибно-червоно. ⚠️ І це звужує читання fraud-лічильника:try_time_sync_recoveryпоглинає категоричний mismatch і робитьreturn trueБЕЗ інкременту, тож «0 фроду» означає «не було АБО поглинуто» — чесний вимір бере ще йtime_unsynced_fallback.
Common Tasks
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 22
- Forks
- 1
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
telemetry-pipeline- Source
- github.com/alexey-lukin/silken_net