# QNE Development Network

`qne-node-v00616` is the first minimal version of the permanent QNE node runtime
for the cross-platform development network. It is not a throwaway bootstrap
node. A later full user install adds the separate UI crate/app, user onboarding,
and user-facing skills on top of the same node runtime.

## First responsibilities

- Create and preserve a local node identity.
- Start the black-box `qne-p2p` manager.
- Run the current `qneskill-node-presence-v00616` skill for presence,
  contact acknowledgement, and session liveness.
- Run the current `qneskill-role-manifest-v00616` skill so nodes obtain
  role-specific qneskill manifests from `development-skill-repo-0001`.
- Maintain a bounded presence cache that replaces old known-node files with
  fresh presence-derived endpoint/capability records.
- Advertise the minimal current `qneskill-gossip-v00616` sync shape for
  presence, role manifest, revocation, network epoch, and artifact records.
- Let `development-master-0001` coordinate installer download sessions before
  Bunny file delivery, creating one bootstrap UUID that becomes the qne-node
  UUID and recording bounded MaxMind/ISP/GeoNames bootstrap hints.
- Classify routes as `internal`, `same-lan`, or `wan`.
- Contact all three Hetzner development roles by default.
- Keep `development-skill-repo-0001` in the default manifest from day one.
- Produce service definitions for macOS LaunchAgent, Linux systemd, and Windows
  service/script bootstrap.

`qne-node` must not implement its own p2p transport. If the existing `qne-p2p`
crate does not expose a needed transport, NAT, DHT, or routing capability, the
needed qne-p2p change must be referred to the founder before editing that crate.

Liveness traffic is not a separate permanent protocol. Normal qneskill traffic
counts as session liveness. The node-presence skill sends liveness/heartbeat
messages only when no data has moved during the liveness interval or when a
presence lease needs refresh.

## Presence Cache

Presence records are node-level and temporary. They are used for current
reachability and capability hints, not for user nicknames or contact aliases.
User routing stays layered:

```text
nickname/contact alias -> user_id -> device/node ids -> presence/endpoints
```

The DHT and cached presence entries only say where a node may be reachable.
qne-p2p session authentication and revocation/capability checks decide whether
the peer is trusted.

Normal nodes use bounded storage:

```text
~/QNE/qne-node/persist/presence/current.json
~/QNE/qne-node/persist/gossip/records/<presence-record-id>.json

max_presence_records = 5000
max_presence_age = 24h
max_presence_bytes = 32MB
presence_ttl = 15m
```

v00616 records are clearly marked as unsigned/session-observed. Production
presence should be signed by the qne-p2p static private key once that stable
identity/signature API exists in qne-p2p.

## Bootstrap Downloads

The first download implementation is intentionally small. `qne-download-
coordinator` creates and claims file-backed download session records under the
master cache. A session includes the browser/header platform guess, optional
request IP and MaxMind ASN/ISP/GeoNames observation, the selected Bunny
artifact, a short-lived nonce hash, and the bootstrap UUID.

The bootstrap UUID is the node UUID after claim. Base qne-node installation does
not create users; user onboarding is a later node/user flow, and some nodes will
never have users.

The installer reports its actual platform with `qne-installer detect-platform`.
If a future wrapper downloaded the wrong runtime, that actual platform value is
the basis for asking master for the correct Bunny artifact. The current crate
does not yet run the public HTTP redirect endpoint.

## Role Provisioning

Startup role is no longer only a local label. A node sends
`qneskill-role-manifest-v00616.request_role_manifest` to its contacts. A
`master-skill-repository` node responds with the manifest for that role.

The node stores the accepted response at:

```text
~/QNE/qne-node/persist/skills/active-role-manifest.json
```

Current roles include:

- `network-master`
- `master-seed`
- `master-skill-repository`
- `linux-builder-x86_64`
- `windows-builder-x86_64`
- `founder`
- `development-node`

The installer has profiles for the three Hetzner development roles:

- `development-master` -> `development-master-0001`, role `network-master`
- `development-seed-master` -> `development-seed-master-0001`, role `master-seed`
- `development-skill-repo` -> `development-skill-repo-0001`, role `master-skill-repository`

Each profile installs the same base node runtime. Role-specific abilities still
arrive through the role manifest skill from the skill repository path.

Builder roles include Hetzner snapshot lifecycle plans. The Linux builder is
proved first; the Windows builder follows the same qneskill shape after the
Linux builder snapshot workflow is accepted.

## Device/user workspace

Each installed development device uses a per-user QNE workspace:

```text
~/QNE/
  qne-node/
    persist/
      lmdb/
      ltr/
      secrets/
  users/
    <base36-user-name>/
      persist/
        lmdb/
        ltr/
        secrets/
  runtimes/
    qne-node-v00616/
  logs/
```

The `qne-node` directory is a sibling of `users`, not a user directory itself.
It owns the device/node persist. Every real user lives under `users` by base36
user name and owns a separate persist tree. Runtime directories are replaceable
install artifacts and should not contain long-lived node or user state.

Every persist root must include the standard major parts from creation:

```text
lmdb/
ltr/
secrets/
```

Those parts may be unused at first, but skills and customization can rely on
the shape being present.

## Storage authority

Source-authority project zips for this development network are stored under:

```text
/dex-network-zips
```

on QNE encrypted online storage backed by the Hetzner Storage Box. Local archive
copies should also be kept under:

```text
~/QNE-archive/dex-network-zips
```

The storage box should be treated as the authority once upload succeeds.

Project zips are source packages, not installer bundles. They should include
source, lockfile, docs, `AGENTS.md`, and bundled doctrine. They should exclude
`target/` and all generated `artifacts/` output. Public installer zips live on
Bunny and are rebuildable from the source package.
