172 lines
6.2 KiB
Markdown
172 lines
6.2 KiB
Markdown
# Device Plane Implementation Baseline
|
|
|
|
Status: local fail-closed foundation implemented; no runtime or production
|
|
mutation.
|
|
|
|
## Product boundary
|
|
|
|
The Device Manager user interface is a canonical Foundry Page Library
|
|
template. Foundry owns page instances, layout, presentation and an opaque
|
|
`device-plane-control` binding. It does not own device records, credentials,
|
|
raw protocol or command delivery.
|
|
|
|
The independent NDC Device Plane owns physical-device state and direct
|
|
connections:
|
|
|
|
```text
|
|
Foundry Device Manager Page
|
|
|
|
|
| device-plane-control (typed server boundary)
|
|
v
|
|
Device Control Core <-> Device PostgreSQL
|
|
|
|
|
v
|
|
Device Gateway <-> physical devices
|
|
```
|
|
|
|
Engine L2 may consume safe decoded observations and build workflows/Data
|
|
Products. It does not own TCP sessions, secrets or the command transport.
|
|
|
|
## Preserved production path
|
|
|
|
The existing Gelios -> Engine L2 -> External Data Plane -> Foundry Map path is
|
|
outside this implementation slice. Its credentials, workflows, Data Products,
|
|
bindings and map presentation must not be changed or restarted by a Device
|
|
Plane artifact.
|
|
|
|
The first B2 pilot adds an NDC server route in parallel and keeps the existing
|
|
Gelios route unchanged.
|
|
|
|
## Source and runtime placement
|
|
|
|
Source:
|
|
|
|
```text
|
|
platform/device-plane/
|
|
packages/device-protocol-contract/
|
|
packages/arusnavi-b2-adapter/
|
|
services/device-control-core/
|
|
services/device-gateway/
|
|
docker-compose.device-plane.yml
|
|
```
|
|
|
|
Planned Synology runtime:
|
|
|
|
```text
|
|
/volume1/docker/nodedc-device-plane
|
|
```
|
|
|
|
Planned Compose project and services:
|
|
|
|
```text
|
|
nodedc-device-plane
|
|
device-control-core
|
|
device-gateway
|
|
device-postgres
|
|
```
|
|
|
|
`device-postgres` is a private persistent prerequisite. Application overlays
|
|
must never force-recreate it or its volume.
|
|
|
|
The canonical runner selects only `device-control-core` and `device-gateway`
|
|
with `--no-deps`. Its health acceptance is scoped to the selected services and
|
|
requires the fail-closed fields to remain disabled. A failed first activation
|
|
removes only candidate stateless services and never requests volume removal.
|
|
|
|
## Network boundary
|
|
|
|
The baseline publishes no device port. The planned pilot ingress is
|
|
`device.nodedc.ru:9921/TCP` only after a port-collision check, quarantine/rate
|
|
limits and a separate reviewed ingress transition.
|
|
|
|
DSM HTTP/HTTPS Reverse Proxy is not a raw TCP ingress and must not be configured
|
|
as `443 -> 9921`.
|
|
|
|
The artifact never changes DSM firewall, DSM Router Configuration, DNS or a
|
|
physical router.
|
|
|
|
## Identity and onboarding
|
|
|
|
An IMEI is a claimed protocol identifier, not proof of tenant ownership.
|
|
|
|
- An unknown connection produces a quarantine-only discovery.
|
|
- A discovery never receives commands.
|
|
- Pilot claim requires an explicit platform-admin action.
|
|
- Production assignment requires authoritative pre-enrollment or an audited
|
|
inventory import.
|
|
- First-claim-wins by IMEI is forbidden.
|
|
|
|
The ARUSNAVI Web account login/password is used only by the human operator to
|
|
configure the additional device route. It is not a Device Plane credential.
|
|
|
|
## Protocol evidence
|
|
|
|
The official B2 material proves:
|
|
|
|
- four simultaneous monitoring server routes;
|
|
- `INTERNAL`, `EXTERNAL`, `USER_AG` and EGTS variants;
|
|
- INTERNAL server-side identification by modem IMEI;
|
|
- server route fields for DNS/IP, TCP port, protocol and optional ID;
|
|
- SMS/TCP command families and a six-digit device access password.
|
|
|
|
The public material inspected so far does not define enough exact INTERNAL
|
|
packet framing and acknowledgement detail to implement a production decoder.
|
|
The B2 adapter therefore hashes bounded evidence and fails closed. It does not
|
|
search arbitrary bytes for a 15-digit sequence and call that an IMEI.
|
|
|
|
## Command boundary
|
|
|
|
Outbound command transport is disabled in this baseline. No command builder is
|
|
exported.
|
|
|
|
Later lifecycle:
|
|
|
|
```text
|
|
draft -> planned -> awaiting_confirmation -> queued -> dispatched
|
|
-> acknowledged | failed | expired | unknown
|
|
```
|
|
|
|
`send` is not success. An `unknown` result forbids automatic retry.
|
|
|
|
Erase, factory reset, firmware/custom firmware, physical outputs and arbitrary
|
|
raw TCP remain forbidden until separate reviewed acceptance slices.
|
|
|
|
## Implemented local foundation
|
|
|
|
- Provider-neutral discovery, contour and opaque Foundry-binding contracts.
|
|
- B2 model profile with four parallel routes and INTERNAL/IMEI evidence.
|
|
- PostgreSQL migration for model profiles, contours, quarantine discoveries,
|
|
claimed devices, Foundry bindings and append-only audit events.
|
|
- Core health endpoint and an authenticated quarantine-ingest boundary that is
|
|
disabled unless explicitly enabled with file-backed secrets.
|
|
- Gateway health endpoint and a loopback-only test listener that records only
|
|
a bounded evidence hash, sends no acknowledgement and emits no identifier.
|
|
- Recursive rejection of secret-like fields, raw payloads and command-shaped
|
|
input in presentation contracts.
|
|
- Automated contract, adapter, migration, Core and Gateway tests.
|
|
- Additive `component=device-plane` runner registry with exact roots, builds,
|
|
services, allowlist/denylist, runner-owned secrets, health contracts and
|
|
automatic source/runtime rollback.
|
|
- Deterministic data-only artifact builder and positive/negative regression
|
|
tests.
|
|
- Compose foundation with a private internal network, preserved PostgreSQL
|
|
volume, file-backed database password and loopback-only health publishing.
|
|
- Exact one-time PostgreSQL bootstrap descriptor, deterministic builder and
|
|
absence preflight: an existing database container or volume fails closed,
|
|
and rollback never removes the volume.
|
|
|
|
## Next source slice
|
|
|
|
1. Review, hash and promote the canonical runner candidate through the
|
|
standalone root administrative gate; do not stage an application artifact
|
|
before fresh `verify-install`.
|
|
2. Build, plan and accept the separate one-time PostgreSQL prerequisite
|
|
bootstrap artifact; ordinary application artifacts must continue to exclude
|
|
the database service.
|
|
3. Obtain or capture the exact official B2 INTERNAL framing and acknowledgement
|
|
contract; keep ingress disabled until its fixtures pass.
|
|
4. Add an authenticated internal Core/Gateway discovery boundary and explicit
|
|
platform-admin claim operation.
|
|
5. Build, audit and stage the first deterministic application artifact only
|
|
after the runner extension is installed and verified.
|