🔧 Fix GitHub Actions docs workflow

- Update mkdocs dependencies to latest versions
- Add permissions for GitHub Pages deployment
- Add workflow_dispatch for manual trigger
- Fix build command with fallback
This commit is contained in:
Apple
2026-01-10 07:57:36 -08:00
parent 90758facae
commit fb4f4a16d5
168 changed files with 124284 additions and 8954 deletions

View File

@@ -0,0 +1,946 @@
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="canonical" href="https://IvanTytar.github.io/microdao-daarion/foundation/Nodes_Interface_Architecture_UPDATE_v1/">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.5.3, mkdocs-material-9.5.18">
<title>Nodes Interface Architecture — UPDATE v1 - DAARION Documentation</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.66ac8b77.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#nodes-interface-architecture-update-v1" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="DAARION Documentation" class="md-header__button md-logo" aria-label="DAARION Documentation" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54Z"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
DAARION Documentation
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Nodes Interface Architecture — UPDATE v1
</span>
</div>
</div>
</div>
<script>var media,input,key,value,palette=__md_get("__palette");if(palette&&palette.color){"(prefers-color-scheme)"===palette.color.media&&(media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']"),palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent"));for([key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="DAARION Documentation" class="md-nav__button md-logo" aria-label="DAARION Documentation" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54Z"/></svg>
</a>
DAARION Documentation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../public/" class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../public/getting-started/" class="md-nav__link">
<span class="md-ellipsis">
Getting Started
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../public/architecture-overview/" class="md-nav__link">
<span class="md-ellipsis">
Architecture
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../public/daiS_daos_overview/" class="md-nav__link">
<span class="md-ellipsis">
DAIS & DAOS
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="">
<span class="md-ellipsis">
Internal
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Internal
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_1" >
<label class="md-nav__link" for="__nav_5_1" id="__nav_5_1_label" tabindex="0">
<span class="md-ellipsis">
Infra
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_1_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_1">
<span class="md-nav__icon md-icon"></span>
Infra
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../internal/infra/INFRA_AUTOMATION_PACK_V1/" class="md-nav__link">
<span class="md-ellipsis">
Infra Automation Pack v1
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../internal/infra/monitoring_overview/" class="md-nav__link">
<span class="md-ellipsis">
Monitoring Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../internal/infra/nodes_registry_v0/" class="md-nav__link">
<span class="md-ellipsis">
Nodes Registry v0
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_2" >
<label class="md-nav__link" for="__nav_5_2" id="__nav_5_2_label" tabindex="0">
<span class="md-ellipsis">
Specs
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_2">
<span class="md-nav__icon md-icon"></span>
Specs
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../internal/specs/matrix_presence_aggregator/" class="md-nav__link">
<span class="md-ellipsis">
Matrix Presence Aggregator
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../internal/specs/city_map_spec/" class="md-nav__link">
<span class="md-ellipsis">
City Map Spec
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../internal/specs/node_join_protocol_draft/" class="md-nav__link">
<span class="md-ellipsis">
Node Join Protocol (Draft)
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="nodes-interface-architecture-update-v1">Nodes Interface Architecture — UPDATE v1<a class="headerlink" href="#nodes-interface-architecture-update-v1" title="Permanent link">&para;</a></h1>
<p>DAARION.city Unified Node Model<br />
Version: 1.1</p>
<hr />
<h1 id="1">1. Визначення НОДИ<a class="headerlink" href="#1" title="Permanent link">&para;</a></h1>
<p><strong>Нода = фізичний об'єкт + локальний обчислювальний модуль + DAIS-агент + запис у таблиці <code>nodes</code>.</strong></p>
<p>Нода не існує "віртуально".<br />
Вона з'являється тільки після фактичного приєднання фізичного пристрою.</p>
<hr />
<h1 id="2">2. Компоненти НОДИ<a class="headerlink" href="#2" title="Permanent link">&para;</a></h1>
<h2 id="21">2.1. Фізичний об'єкт ("ресурс")<a class="headerlink" href="#21" title="Permanent link">&para;</a></h2>
<ul>
<li>енергетична установка, </li>
<li>обчислювальний сервер, </li>
<li>IoT-станція, </li>
<li>мікрокомп'ютер або смартфон, </li>
<li>будь-яка реальна точка у світі.</li>
</ul>
<h2 id="22">2.2. Локальний мозок<a class="headerlink" href="#22" title="Permanent link">&para;</a></h2>
<p>Обов'язково існує хоча б один пристрій, здатний:</p>
<ul>
<li>запускати агента, </li>
<li>передавати телеметрію, </li>
<li>встановлювати з'єднання з DAARION, </li>
<li>керувати локальним обладнанням.</li>
</ul>
<p>Це може бути:</p>
<ul>
<li>ноутбук,</li>
<li>міні-ПК,</li>
<li>сервер,</li>
<li>смартфон,</li>
<li>Raspberry Pi.</li>
</ul>
<h2 id="23-dais-">2.3. DAIS-агент<a class="headerlink" href="#23-dais-" title="Permanent link">&para;</a></h2>
<p>Кожна нода має свого:</p>
<ul>
<li><code>dais_id</code> </li>
<li><code>wallet</code> </li>
<li><code>public_key</code> </li>
<li><code>role: node_agent</code> </li>
</ul>
<p>Це і є "особистість" ноди, можливість підписувати операції.</p>
<h2 id="24-nodes">2.4. Запис у таблиці <code>nodes</code><a class="headerlink" href="#24-nodes" title="Permanent link">&para;</a></h2>
<p>У БД фіксується:</p>
<ul>
<li><code>node_id</code> </li>
<li><code>owner_microdao_id</code> </li>
<li><code>node_agent_id</code> </li>
<li><code>kind</code> </li>
<li><code>capabilities</code> </li>
<li><code>status</code> </li>
<li><code>registered_at</code> </li>
</ul>
<h2 id="25-node-profile-core-invariants-patch-v1">2.5. Node Profile — Core Invariants (PATCH v1)<a class="headerlink" href="#25-node-profile-core-invariants-patch-v1" title="Permanent link">&para;</a></h2>
<p>Кожна нода в DAARION Ontology має чотири обов'язкові шари:</p>
<ol>
<li><strong>Metrics Layer</strong> — live-метрики CPU/GPU/RAM/Disk + heartbeat. Навіть якщо телеметрія частково відсутня, нода переходить у <code>metrics_status = degraded</code>, а не існує “порожньою”.</li>
<li><strong>Ownership Layer</strong> — власник (MicroDAO/District) з полями <code>owner_microdao_id</code>, <code>owner_microdao_slug</code> (опційно <code>district_id</code>). Немає безхазяйних нод.</li>
<li><strong>Models Layer</strong> — локальний Swapper + набір моделей (LLM, STT, vision, TTS, RAG). Dev-ноди так само мають DAGI-стек, просто з іншим складом моделей.</li>
<li><strong>Orchestration Layer</strong> — локальний DAGI Router + агенти з <code>home_node_id</code>, які працюють на цій ноді.</li>
</ol>
<p>Також кожна нода має мінімальний набір <strong>Node Core Agents</strong>:</p>
<ul>
<li><strong>Node Guardian Agent</strong> — відповідає за health, безпеку, інциденти.</li>
<li><strong>Node Steward Agent</strong> — відповідає за приналежність до microDAO, профіль, онбординг.</li>
<li>(опційно) <strong>Node Models/Swapper Agent</strong> — відповідає за опис і політику використання локального стека моделей.</li>
</ul>
<blockquote>
<p>Принцип “немає сторінки без агентів” означає, що будь-який інтерфейс Ноди (профіль, метрики, моделі, доступи) завжди “закріплений” за хоча б одним агентом, і цей агент показується в UI.</p>
</blockquote>
<hr />
<h1 id="3">3. Типи НОД<a class="headerlink" href="#3" title="Permanent link">&para;</a></h1>
<h2 id="31-energy-node">3.1. Energy Node<a class="headerlink" href="#31-energy-node" title="Permanent link">&para;</a></h2>
<p>Фізична енергетична установка з датчиками.</p>
<p><code>kind = "energy"</code></p>
<h2 id="32-compute-node">3.2. Compute Node<a class="headerlink" href="#32-compute-node" title="Permanent link">&para;</a></h2>
<p>Фізичний сервер/станція для AI.</p>
<p><code>kind = "compute"</code></p>
<h2 id="33-hybrid-node">3.3. Hybrid Node<a class="headerlink" href="#33-hybrid-node" title="Permanent link">&para;</a></h2>
<p>Енергія + compute.</p>
<p><code>kind = "hybrid"</code></p>
<h2 id="34-iot-gateway-node">3.4. IoT Gateway Node<a class="headerlink" href="#34-iot-gateway-node" title="Permanent link">&para;</a></h2>
<p>Для сенсорних мереж.</p>
<p><code>kind = "iot_gateway"</code></p>
<h2 id="35-edge-node">3.5. Edge Node<a class="headerlink" href="#35-edge-node" title="Permanent link">&para;</a></h2>
<p>Смартфон, ноутбук, міні-ПК.</p>
<p><code>kind = "edge"</code></p>
<h2 id="36-datacenter-node">3.6. Datacenter Node<a class="headerlink" href="#36-datacenter-node" title="Permanent link">&para;</a></h2>
<p>Потужний серверний вузол.</p>
<p><code>kind = "datacenter"</code></p>
<h2 id="37-gpu-cluster-node">3.7. GPU Cluster Node<a class="headerlink" href="#37-gpu-cluster-node" title="Permanent link">&para;</a></h2>
<p>Спеціалізований GPU кластер.</p>
<p><code>kind = "gpu_cluster"</code></p>
<hr />
<h1 id="4-capability-">4. Capability-профілі ("можливості")<a class="headerlink" href="#4-capability-" title="Permanent link">&para;</a></h1>
<p>При реєстрації ноди описуються її можливості:</p>
<h3 id="_1">Приклади:<a class="headerlink" href="#_1" title="Permanent link">&para;</a></h3>
<div class="codehilite"><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;energy&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>
<span class="w"> </span><span class="nt">&quot;max_kWt&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">8.2</span><span class="p">,</span><span class="w"> </span>
<span class="w"> </span><span class="nt">&quot;sensors&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;temp&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;co2&quot;</span><span class="p">],</span><span class="w"> </span>
<span class="w"> </span><span class="nt">&quot;telemetry&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;1m&quot;</span><span class="w"> </span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;compute&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>
<span class="w"> </span><span class="nt">&quot;gpu_vram&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;16GB&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="w"> </span><span class="nt">&quot;cpu_cores&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">12</span><span class="p">,</span><span class="w"> </span>
<span class="w"> </span><span class="nt">&quot;ram&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;64GB&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;storage&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;2TB&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>Цей профіль створюється самим пристроєм або оператором вручну.</p>
<hr />
<h1 id="5">5. Правило реєстрації<a class="headerlink" href="#5" title="Permanent link">&para;</a></h1>
<blockquote>
<p>Нода реєструється тільки тоді, коли фізичний пристрій реально з'єднується з DAARION і викликає <code>/nodes/register</code>.</p>
</blockquote>
<p><strong>Жодних автосозданих нод.</strong><br />
<strong>Жодних "placeholder-node".</strong></p>
<h2 id="51">5.1 Процес реєстрації<a class="headerlink" href="#51" title="Permanent link">&para;</a></h2>
<div class="codehilite"><pre><span></span><code><span class="n">sequenceDiagram</span>
<span class="w"> </span><span class="n">participant</span><span class="w"> </span><span class="n">Device</span><span class="w"> </span><span class="n">as</span><span class="w"> </span><span class="n">Physical</span><span class="w"> </span><span class="n">Device</span>
<span class="w"> </span><span class="n">participant</span><span class="w"> </span><span class="n">Brain</span><span class="w"> </span><span class="n">as</span><span class="w"> </span><span class="n">Local</span><span class="w"> </span><span class="n">Brain</span>
<span class="w"> </span><span class="n">participant</span><span class="w"> </span><span class="n">API</span><span class="w"> </span><span class="n">as</span><span class="w"> </span><span class="n">DAARION</span><span class="w"> </span><span class="n">API</span>
<span class="w"> </span><span class="n">participant</span><span class="w"> </span><span class="n">DB</span><span class="w"> </span><span class="n">as</span><span class="w"> </span><span class="n">Database</span>
<span class="w"> </span><span class="n">Device</span><span class="o">-&gt;&gt;</span><span class="nl">Brain:</span><span class="w"> </span><span class="n">Boot</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="n">Initialize</span>
<span class="w"> </span><span class="n">Brain</span><span class="o">-&gt;&gt;</span><span class="nl">API:</span><span class="w"> </span><span class="n">POST</span><span class="w"> </span><span class="o">/</span><span class="n">nodes</span><span class="o">/</span><span class="n">register</span>
<span class="w"> </span><span class="n">API</span><span class="o">-&gt;&gt;</span><span class="nl">API:</span><span class="w"> </span><span class="n">Validate</span><span class="w"> </span><span class="n">DAIS</span><span class="w"> </span><span class="n">identity</span>
<span class="w"> </span><span class="n">API</span><span class="o">-&gt;&gt;</span><span class="nl">DB:</span><span class="w"> </span><span class="n">INSERT</span><span class="w"> </span><span class="n">INTO</span><span class="w"> </span><span class="n">nodes</span>
<span class="w"> </span><span class="n">DB</span><span class="o">--&gt;&gt;</span><span class="nl">API:</span><span class="w"> </span><span class="n">node_id</span>
<span class="w"> </span><span class="n">API</span><span class="o">--&gt;&gt;</span><span class="nl">Brain:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">node_id</span><span class="p">,</span><span class="w"> </span><span class="nl">status:</span><span class="w"> </span><span class="s">&quot;registered&quot;</span><span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">Brain</span><span class="o">-&gt;&gt;</span><span class="nl">Device:</span><span class="w"> </span><span class="n">Configure</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="n">Start</span><span class="w"> </span><span class="n">Services</span>
</code></pre></div>
<h2 id="52-required-fields">5.2 Required Fields<a class="headerlink" href="#52-required-fields" title="Permanent link">&para;</a></h2>
<table>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>owner_microdao_id</td>
<td>UUID</td>
<td></td>
<td>MicroDAO власник</td>
</tr>
<tr>
<td>node_agent_id</td>
<td>TEXT</td>
<td></td>
<td>DAIS ID агента ноди</td>
</tr>
<tr>
<td>kind</td>
<td>ENUM</td>
<td></td>
<td>Тип ноди</td>
</tr>
<tr>
<td>capabilities</td>
<td>JSONB</td>
<td></td>
<td>Можливості</td>
</tr>
<tr>
<td>hostname</td>
<td>TEXT</td>
<td></td>
<td>Ім'я хоста</td>
</tr>
<tr>
<td>ip_address</td>
<td>TEXT</td>
<td></td>
<td>IP адреса</td>
</tr>
</tbody>
</table>
<hr />
<h1 id="6-onboarding-offboarding">6. Onboarding / Offboarding<a class="headerlink" href="#6-onboarding-offboarding" title="Permanent link">&para;</a></h1>
<h2 id="61-onboarding">6.1 Onboarding<a class="headerlink" href="#61-onboarding" title="Permanent link">&para;</a></h2>
<ol>
<li>Фізичний пристрій підключається до мережі</li>
<li>Локальний мозок запускає DAIS-агента</li>
<li>Агент отримує DAIS identity (якщо ще немає)</li>
<li>Виклик <code>/nodes/register</code> з capability-профілем</li>
<li>Нода з'являється в системі</li>
<li>District Lead Agent підтверджує (якщо потрібно)</li>
</ol>
<h2 id="62-offboarding">6.2 Offboarding<a class="headerlink" href="#62-offboarding" title="Permanent link">&para;</a></h2>
<ul>
<li>власник може відключити ноду через <code>/nodes/{id}/deactivate</code></li>
<li>District Lead може заблокувати ноду при порушенні</li>
<li>City Governance може ревокувати ноду при критичних інцидентах</li>
</ul>
<hr />
<h1 id="7-security">7. Security<a class="headerlink" href="#7-security" title="Permanent link">&para;</a></h1>
<ul>
<li>всі операції підписані DAIS-ключами ноди</li>
<li>ревокація ноди = блокування її DAIS-агента</li>
<li>телеметрія може бути E2E-шифрована</li>
<li>кожна нода має свій wallet для мікротранзакцій</li>
</ul>
<h2 id="71-key-rotation">7.1 Key Rotation<a class="headerlink" href="#71-key-rotation" title="Permanent link">&para;</a></h2>
<p>Ноди повинні періодично оновлювати ключі:</p>
<ul>
<li>автоматична ротація кожні 90 днів</li>
<li>примусова ротація при підозрі компрометації</li>
<li>старі ключі зберігаються в <code>dais_keys</code> з <code>revoked = true</code></li>
</ul>
<hr />
<h1 id="8-district-">8. Інтеграція з District-протоколами<a class="headerlink" href="#8-district-" title="Permanent link">&para;</a></h1>
<h2 id="81-microdao">8.1 MicroDAO<a class="headerlink" href="#81-microdao" title="Permanent link">&para;</a></h2>
<p>Кожна нода належить певному MicroDAO:</p>
<ul>
<li><code>owner_microdao_id</code> → FK до <code>microdaos</code></li>
<li>права управління нодою = права Orchestrator MicroDAO</li>
</ul>
<h2 id="82-district">8.2 District<a class="headerlink" href="#82-district" title="Permanent link">&para;</a></h2>
<p>District Lead (Helion, GREENFOOD ERP, інші) має право:</p>
<ul>
<li>реєстрації ноди всередині District</li>
<li>перевірки capability-профілю</li>
<li>блокування ноди в разі порушення протоколу</li>
<li>налаштування SLA вимог</li>
</ul>
<h2 id="83-city">8.3 City<a class="headerlink" href="#83-city" title="Permanent link">&para;</a></h2>
<p>City Governance може:</p>
<ul>
<li>переглядати всі ноди міста з роллю <code>city_governance</code></li>
<li>блокувати ноди при критичних інцидентах</li>
<li>встановлювати city-wide policies</li>
</ul>
<hr />
<h1 id="9-node-status-lifecycle">9. Node Status Lifecycle<a class="headerlink" href="#9-node-status-lifecycle" title="Permanent link">&para;</a></h1>
<div class="codehilite"><pre><span></span><code><span class="n">registered</span><span class="w"> </span><span class="err"></span><span class="w"> </span><span class="n">online</span><span class="w"> </span><span class="err"></span><span class="w"> </span><span class="n">busy</span><span class="w"> </span><span class="err"></span><span class="w"> </span><span class="n">offline</span><span class="w"> </span><span class="err"></span><span class="w"> </span><span class="n">deactivated</span>
<span class="w"> </span><span class="err"></span>
<span class="w"> </span><span class="n">suspended</span><span class="w"> </span><span class="p">(</span><span class="err">при</span><span class="w"> </span><span class="err">порушенні</span><span class="p">)</span>
<span class="w"> </span><span class="err"></span>
<span class="w"> </span><span class="n">revoked</span><span class="w"> </span><span class="p">(</span><span class="n">hard</span><span class="w"> </span><span class="n">block</span><span class="p">)</span>
</code></pre></div>
<table>
<thead>
<tr>
<th>Status</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>registered</code></td>
<td>Нода зареєстрована, очікує активації</td>
</tr>
<tr>
<td><code>online</code></td>
<td>Нода активна, готова до роботи</td>
</tr>
<tr>
<td><code>busy</code></td>
<td>Нода виконує задачу</td>
</tr>
<tr>
<td><code>offline</code></td>
<td>Нода тимчасово недоступна</td>
</tr>
<tr>
<td><code>suspended</code></td>
<td>Нода призупинена адміністративно</td>
</tr>
<tr>
<td><code>deactivated</code></td>
<td>Нода деактивована власником</td>
</tr>
<tr>
<td><code>revoked</code></td>
<td>Нода заблокована назавжди</td>
</tr>
</tbody>
</table>
<hr />
<h1 id="10-telemetry-protocol">10. Telemetry Protocol<a class="headerlink" href="#10-telemetry-protocol" title="Permanent link">&para;</a></h1>
<h2 id="101-heartbeat">10.1 Heartbeat<a class="headerlink" href="#101-heartbeat" title="Permanent link">&para;</a></h2>
<p>Кожна нода надсилає heartbeat кожні 60 секунд:</p>
<div class="codehilite"><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;node_id&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;...&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;timestamp&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;2025-11-30T12:00:00Z&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;online&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;metrics&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;cpu_load&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">0.45</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;memory_used&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">0.67</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;disk_free&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">0.82</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<h2 id="102-nats-subjects">10.2 NATS Subjects<a class="headerlink" href="#102-nats-subjects" title="Permanent link">&para;</a></h2>
<ul>
<li><code>nodes.heartbeat.{node_id}</code> — heartbeat</li>
<li><code>nodes.metrics.{node_id}</code> — детальна телеметрія</li>
<li><code>nodes.events.{node_id}</code> — події ноди</li>
<li><code>nodes.alerts.{node_id}</code> — алерти</li>
</ul>
<hr />
<h1 id="11">11. Сумісність<a class="headerlink" href="#11" title="Permanent link">&para;</a></h1>
<p>Ця модель однакова для:</p>
<ul>
<li><strong>Energy Union</strong> — energy/compute/hybrid ноди</li>
<li><strong>GREENFOOD</strong> — warehouse/logistics/iot ноди</li>
<li><strong>CLAN</strong> — edge/compute ноди</li>
<li><strong>SOUL</strong> — personal/edge ноди</li>
<li><strong>DAARION root DAO</strong> — datacenter/gpu_cluster ноди</li>
</ul>
<hr />
<h1 id="12-cross-references">12. Cross-References<a class="headerlink" href="#12-cross-references" title="Permanent link">&para;</a></h1>
<ul>
<li><strong>DAARION_Ontology_Core_v1.md</strong> — базова онтологія</li>
<li><strong>DAIS_Layer_Architecture_v1.md</strong> — система ідентичності</li>
<li><strong>Agent_Governance_Protocol_v1.md</strong> — права агентів</li>
<li><strong>ENERGYUNION_District_Protocol_v1.md</strong> — протокол Energy Union</li>
<li><strong>GREENFOOD_District_Protocol_v1.md</strong> — протокол GREENFOOD</li>
</ul>
<hr />
<p><strong>Document Status:</strong> ✅ Ready for Implementation</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": ["navigation.sections", "navigation.instant", "content.code.copy"], "search": "../../assets/javascripts/workers/search.b8dbb3d2.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
<script src="../../assets/javascripts/bundle.3220b9d7.min.js"></script>
</body>
</html>