Compare commits
3 Commits
1749f9b4ad
...
cae7c2b171
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cae7c2b171 | ||
|
|
64f83d4392 | ||
|
|
454a681a50 |
@@ -44,6 +44,102 @@ Real-model/hardware stories must:
|
||||
|
||||
Before a story is marked complete, run the full deterministic `pytest -q` suite or record the exact pre-existing unrelated failure with a clean-tree reproduction.
|
||||
|
||||
## Dependency Graph and Status
|
||||
|
||||
Status as of 2026-07-14 (MAINT-003). Authoritative per-story status is
|
||||
`passes` in [prd.json](prd.json); closed issues live in
|
||||
`docs/issues/distributed-gguf-runtime/`, open and blocked issues in
|
||||
[issues/](issues/).
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
classDef done fill:#c8e6c9,stroke:#2e7d32;
|
||||
classDef blocked fill:#ffcdd2,stroke:#c62828;
|
||||
|
||||
DGR001[DGR-001 perf contract]:::done
|
||||
DGR002[DGR-002 gRPC Shard protocol]:::done
|
||||
DGR003[DGR-003 artifact/recipe identity]:::done
|
||||
DGR004[DGR-004 pinned llama.cpp patch stack]:::done
|
||||
DGR005[DGR-005 dense-Llama range ownership]:::done
|
||||
DGR006[DGR-006 boundary input/output]:::done
|
||||
DGR017[DGR-017 GLM-5.2 target/alpha contract]:::done
|
||||
DGR018[DGR-018 whole-model GLM oracle]:::blocked
|
||||
DGR019[DGR-019 GLM range/DSA/IndexShare]:::blocked
|
||||
DGR020[DGR-020 distributed GLM alpha]:::blocked
|
||||
DGR007[DGR-007 Hot KV State]
|
||||
DGR008[DGR-008 C++ gRPC worker]
|
||||
DGR009[DGR-009 Meshnet integration]
|
||||
DGR010[DGR-010 local two-process acceptance]
|
||||
DGR011[DGR-011 two-machine route]
|
||||
DGR012[DGR-012 continuous batching]
|
||||
DGR013[DGR-013 failure/cancel/restart]
|
||||
DGR014[DGR-014 release gate]
|
||||
DGR015[DGR-015 Qwen3 adapter]
|
||||
DGR016[DGR-016 upstream package]
|
||||
|
||||
DGR002 --> DGR003
|
||||
DGR017 --> DGR003
|
||||
DGR001 --> DGR004
|
||||
DGR017 --> DGR004
|
||||
DGR003 --> DGR005
|
||||
DGR004 --> DGR005
|
||||
DGR002 --> DGR006
|
||||
DGR005 --> DGR006
|
||||
DGR001 --> DGR017
|
||||
DGR002 --> DGR017
|
||||
DGR003 --> DGR018
|
||||
DGR004 --> DGR018
|
||||
DGR017 --> DGR018
|
||||
DGR005 --> DGR019
|
||||
DGR006 --> DGR019
|
||||
DGR018 --> DGR019
|
||||
DGR006 --> DGR007
|
||||
DGR019 --> DGR007
|
||||
DGR002 --> DGR008
|
||||
DGR003 --> DGR008
|
||||
DGR004 --> DGR008
|
||||
DGR006 --> DGR008
|
||||
DGR007 --> DGR008
|
||||
DGR003 --> DGR009
|
||||
DGR008 --> DGR009
|
||||
DGR009 --> DGR010
|
||||
DGR010 --> DGR011
|
||||
DGR007 --> DGR012
|
||||
DGR009 --> DGR012
|
||||
DGR010 --> DGR012
|
||||
DGR008 --> DGR013
|
||||
DGR009 --> DGR013
|
||||
DGR001 --> DGR014
|
||||
DGR011 --> DGR014
|
||||
DGR012 --> DGR014
|
||||
DGR013 --> DGR014
|
||||
DGR014 --> DGR015
|
||||
DGR010 --> DGR016
|
||||
DGR007 --> DGR020
|
||||
DGR008 --> DGR020
|
||||
DGR009 --> DGR020
|
||||
DGR011 --> DGR020
|
||||
DGR013 --> DGR020
|
||||
DGR017 --> DGR020
|
||||
DGR018 --> DGR020
|
||||
DGR019 --> DGR020
|
||||
```
|
||||
|
||||
- **Done (`passes: true`):** DGR-001, DGR-002, DGR-003, DGR-004, DGR-005,
|
||||
DGR-006, DGR-017.
|
||||
- **Blocked on hardware:** DGR-018 requires a 256-GiB-class host with at least
|
||||
224 GiB runtime-accessible memory and 250 GB free storage outside `/home`;
|
||||
no such host is currently available (development host: 124.9 GiB MemTotal).
|
||||
Exact preflight output: [evidence/DGR-018/BLOCKED.md](evidence/DGR-018/BLOCKED.md).
|
||||
DGR-019 (needs the DGR-018 oracle) and DGR-020 (needs DGR-018/DGR-019 plus
|
||||
multiple physical consumer nodes) are blocked transitively.
|
||||
- **Consequence of the graph as written:** DGR-007 depends on DGR-019, so every
|
||||
remaining story (DGR-007 through DGR-016) is transitively blocked on the
|
||||
256-GiB host. Unblocking the generic dense pipeline without that host would
|
||||
require an explicit re-planning decision to relax the DGR-007 → DGR-019
|
||||
dependency; that decision is out of scope for maintenance and has not been
|
||||
made.
|
||||
|
||||
## User Stories
|
||||
|
||||
### DGR-001: Lock the safetensors-versus-GGUF performance contract
|
||||
|
||||
@@ -7,20 +7,23 @@ real-model integration (TinyLlama 1.1B, opt-in via MESHNET_ENABLE_REAL_INFERENCE
|
||||
|
||||
All six acceptance criteria pass:
|
||||
|
||||
1. **Range-aware tensor ownership**: native C++ patch (`0002-dense-llama-owned-range-loader.patch`)
|
||||
1. **Range-aware tensor ownership**: native C++ patch (`0002-dense-llama-owned-range-loader.patch`,
|
||||
169 lines as merged — DGR-005A's original 365-line version was slimmed by DGR-005B)
|
||||
adds `llama_model_params.meshnet_owned_layer_start/end`, `llama_meshnet_range_report`,
|
||||
and restricts `blk.N.*` registration to the owned range.
|
||||
2. **Head/tail embedding loading**: head loads `token_embd.weight`; tail loads `output_norm`/`output`
|
||||
(with tied-embedding dedup). Middle shards load zero endpoint tensors.
|
||||
3. **Mapped/resident memory scales with owned tensors**: proven with TinyLlama 1.1B Q4_K_M.
|
||||
4. **Targeted pytest tests**: `tests/test_llama_cpp_dependency.py` (47 passed), native CTest
|
||||
(`test-meshnet-range-ownership` synthetic fixture).
|
||||
4. **Targeted pytest tests**: `tests/test_llama_cpp_dependency.py` (3 tests — lock/patch
|
||||
manifest consistency, offline dependency report, control-plane-code scan; re-verified
|
||||
2026-07-14: `3 passed, 6 skipped` together with the opt-in integration file), native CTest
|
||||
(`test-meshnet-range-ownership` synthetic fixture, added by the 0002 patch).
|
||||
5. **compileall, ruff, git diff --check, full pytest**: all pass.
|
||||
6. **Integration test**: `tests/test_gguf_distributed_load.py` (6/6, opt-in real model).
|
||||
|
||||
## Files changed (vs HEAD at DGR-004)
|
||||
|
||||
- `packages/node/native/llama/patches/0002-dense-llama-owned-range-loader.patch` — 365-line native patch
|
||||
- `packages/node/native/llama/patches/0002-dense-llama-owned-range-loader.patch` — 169-line native patch (as merged)
|
||||
- `packages/node/native/llama/patches/SHA256SUMS` — updated hash
|
||||
- `packages/node/native/llama/patches/series` — added patch to series
|
||||
- `packages/node/native/llama/UPSTREAM_LOCK.json` — updated patched_tree, serial number
|
||||
|
||||
@@ -61,7 +61,7 @@ New — runtime-loadable package (single source of truth):
|
||||
| `packages/node/meshnet_node/glm_alpha/data/architecture-snapshot.json` | Pinned architecture + config/template hashes |
|
||||
| `packages/node/meshnet_node/glm_alpha/data/alpha-contract.json` | Sealed acceptance thresholds (`aab23220…`) |
|
||||
| `scripts/refresh_glm_target_manifest.py` | Re-resolve/verify pins from upstream metadata (`--check` / `--write`) |
|
||||
| `tests/test_glm_alpha_target.py` | 97 deterministic offline tests |
|
||||
| `tests/test_glm_alpha_target.py` | 97 deterministic offline tests (99 after the late-review repair — see §4a) |
|
||||
|
||||
New — evidence:
|
||||
|
||||
@@ -130,6 +130,15 @@ completed), then passed **5/5** in isolation and passed in the integrated full-s
|
||||
rerun above. This story touches no tracker code; the failed run is retained in
|
||||
`commands.txt` rather than hidden.
|
||||
|
||||
### 4a. Late independent-review repair (2026-07-14)
|
||||
|
||||
During delayed DGR-003 review, two contract-continuity defects were found and
|
||||
fixed here: v1 now has an independently trusted digest pinned in code
|
||||
(`test_resealing_a_mutated_v1_contract_is_rejected`) and parsed nested contract
|
||||
state is recursively immutable. This added two tests; the suite is now
|
||||
**99 passed** (`commands.txt` §7 records the exact runs). All "97" figures
|
||||
elsewhere in this README describe the suite at original completion.
|
||||
|
||||
Planner output (`resource-plan.json`):
|
||||
|
||||
| Route | Fits | Headroom |
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# DGR-018 — BLOCKED: no 256-GiB-class oracle host
|
||||
|
||||
Recorded: 2026-07-14 (MAINT-003). Preflight scripts preserved at commit
|
||||
`a0f28b5` ("chore: preserve DGR-018 preflight scripts (postponed)").
|
||||
|
||||
## Blocker
|
||||
|
||||
DGR-018 requires a 256-GiB-class host with at least **224 GiB
|
||||
runtime-accessible memory** (the DGR-017 experimental hard-fit floor for the
|
||||
whole-model `UD-IQ1_S` oracle) and **250 GB free storage** on one filesystem
|
||||
outside `/home` (216.715 GB artifact plus resume/temp headroom). The available
|
||||
development host fails both gates, so the whole-model oracle cannot be
|
||||
established. Per the issue's finish contract, no smaller model may be
|
||||
substituted.
|
||||
|
||||
DGR-019 (needs the DGR-018 oracle for parity certification) and DGR-020
|
||||
(needs DGR-018 and DGR-019, plus enough physical consumer nodes that no single
|
||||
node admits the whole recipe) are blocked transitively.
|
||||
|
||||
## Exact preflight output
|
||||
|
||||
Command (offline; resolves everything from the pinned target manifest and
|
||||
never contacts the network):
|
||||
|
||||
```
|
||||
$ python scripts/glm_whole_model_preflight.py
|
||||
target: UD-IQ1_S 216.715 GB, 6 shards @ abc55e725277
|
||||
[FAIL] storage: need >= 250 GB free on one filesystem outside ['/home']; observed no eligible filesystem
|
||||
[FAIL] memory: need >= 224 GiB runtime-accessible memory (DGR-017 experimental hard-fit floor); observed 124.9 GiB MemTotal
|
||||
destination: NONE — no filesystem outside ['/home'] has 250 GB free
|
||||
- /run/media/popov/DATA (ext4): 74.2 GB free
|
||||
- / (ext4): 51.1 GB free
|
||||
- /run/media/popov/Windows (fuseblk): 26.0 GB free
|
||||
- /run/media/popov/d (fuseblk): 5.1 GB free
|
||||
verdict: fail
|
||||
$ echo $?
|
||||
1
|
||||
```
|
||||
|
||||
Host: Linux 7.0.14-101.fc43.x86_64 x86_64, `MemTotal: 130997376 kB`
|
||||
(124.9 GiB). The full machine-readable report (including the ordered
|
||||
download/verify plan against revision `abc55e72527792c6e77069c99b4cb7de16fa9f23`,
|
||||
manifest SHA-256 `0b6aed04479d204902bb64c0203f1a46cab26a47b378ecccf85237b63f6c1962`)
|
||||
is in [preflight.json](preflight.json).
|
||||
|
||||
## How to resume
|
||||
|
||||
1. On a qualifying host, run `python scripts/glm_whole_model_preflight.py`
|
||||
(optionally `--dest DIR`); it must exit 0 with `verdict: pass`.
|
||||
2. Download shards in the preflight's ordered plan; verify each with
|
||||
`python scripts/verify_glm_shards.py` before the next transfer starts.
|
||||
3. Proceed with the DGR-018 issue
|
||||
(`.scratch/distributed-gguf-runtime/issues/18-certify-whole-model-glm-5-2-runtime-semantics.md`).
|
||||
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"generated_by": "scripts/glm_whole_model_preflight.py",
|
||||
"target": {
|
||||
"gguf_repo_id": "unsloth/GLM-5.2-GGUF",
|
||||
"gguf_revision": "abc55e72527792c6e77069c99b4cb7de16fa9f23",
|
||||
"quantization": "UD-IQ1_S",
|
||||
"shard_count": 6,
|
||||
"total_bytes": 216715360960,
|
||||
"total_gb": 216.715,
|
||||
"manifest_sha256": "0b6aed04479d204902bb64c0203f1a46cab26a47b378ecccf85237b63f6c1962"
|
||||
},
|
||||
"forbidden_path_prefixes": [
|
||||
"/home"
|
||||
],
|
||||
"mounts": [
|
||||
{
|
||||
"mountpoint": "/run/media/popov/DATA",
|
||||
"fstype": "ext4",
|
||||
"total_gb": 1208.8,
|
||||
"free_gb": 74.2,
|
||||
"free_bytes": 74201321472,
|
||||
"forbidden": false,
|
||||
"eligible": false
|
||||
},
|
||||
{
|
||||
"mountpoint": "/",
|
||||
"fstype": "ext4",
|
||||
"total_gb": 217.7,
|
||||
"free_gb": 51.1,
|
||||
"free_bytes": 51073683456,
|
||||
"forbidden": false,
|
||||
"eligible": false
|
||||
},
|
||||
{
|
||||
"mountpoint": "/run/media/popov/Windows",
|
||||
"fstype": "fuseblk",
|
||||
"total_gb": 434.9,
|
||||
"free_gb": 26.0,
|
||||
"free_bytes": 25964466176,
|
||||
"forbidden": false,
|
||||
"eligible": false
|
||||
},
|
||||
{
|
||||
"mountpoint": "/run/media/popov/d",
|
||||
"fstype": "fuseblk",
|
||||
"total_gb": 161.1,
|
||||
"free_gb": 5.1,
|
||||
"free_bytes": 5148332032,
|
||||
"forbidden": false,
|
||||
"eligible": false
|
||||
}
|
||||
],
|
||||
"chosen_destination": null,
|
||||
"checks": [
|
||||
{
|
||||
"check": "storage",
|
||||
"requirement": ">= 250 GB free on one filesystem outside ['/home']",
|
||||
"observed": "no eligible filesystem",
|
||||
"passes": false
|
||||
},
|
||||
{
|
||||
"check": "memory",
|
||||
"requirement": ">= 224 GiB runtime-accessible memory (DGR-017 experimental hard-fit floor)",
|
||||
"observed": "124.9 GiB MemTotal",
|
||||
"passes": false,
|
||||
"waived": false
|
||||
}
|
||||
],
|
||||
"download_authorized": false,
|
||||
"storage_only": false,
|
||||
"download_plan": [
|
||||
{
|
||||
"step": 1,
|
||||
"shard_index": 1,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00001-of-00006.gguf",
|
||||
"size_bytes": 9423744,
|
||||
"size_gb": 0.009,
|
||||
"sha256": "46b6148389219ae45167cb8124fbb18ef7d432daf619b4faf9e06ea80d3f4777",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00001-of-00006.gguf",
|
||||
"download_command": "curl -L -C - --fail -o \"$GLM_DEST/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00001-of-00006.gguf\" \"https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00001-of-00006.gguf\"",
|
||||
"verify_command": "python scripts/verify_glm_shards.py --model-dir \"$GLM_DEST\" --shard 1"
|
||||
},
|
||||
{
|
||||
"step": 2,
|
||||
"shard_index": 6,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00006-of-00006.gguf",
|
||||
"size_bytes": 19171063136,
|
||||
"size_gb": 19.171,
|
||||
"sha256": "3b767f55df64e0432d52fcf1a14eb47a1ef3bbc91339e2ae220f38602237d7d7",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00006-of-00006.gguf",
|
||||
"download_command": "curl -L -C - --fail -o \"$GLM_DEST/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00006-of-00006.gguf\" \"https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00006-of-00006.gguf\"",
|
||||
"verify_command": "python scripts/verify_glm_shards.py --model-dir \"$GLM_DEST\" --shard 6"
|
||||
},
|
||||
{
|
||||
"step": 3,
|
||||
"shard_index": 2,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00002-of-00006.gguf",
|
||||
"size_bytes": 49208128256,
|
||||
"size_gb": 49.208,
|
||||
"sha256": "f2180207285e04fcaa5b8c53ba6e77ad5cc58666b6e7c6b04a5eded3fe8bef09",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00002-of-00006.gguf",
|
||||
"download_command": "curl -L -C - --fail -o \"$GLM_DEST/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00002-of-00006.gguf\" \"https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00002-of-00006.gguf\"",
|
||||
"verify_command": "python scripts/verify_glm_shards.py --model-dir \"$GLM_DEST\" --shard 2"
|
||||
},
|
||||
{
|
||||
"step": 4,
|
||||
"shard_index": 3,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00003-of-00006.gguf",
|
||||
"size_bytes": 49684417024,
|
||||
"size_gb": 49.684,
|
||||
"sha256": "b1c0c5a302cc8d5d9ea0bcd4467c01db72c26839f820f7e882079582ea0a8d2b",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00003-of-00006.gguf",
|
||||
"download_command": "curl -L -C - --fail -o \"$GLM_DEST/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00003-of-00006.gguf\" \"https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00003-of-00006.gguf\"",
|
||||
"verify_command": "python scripts/verify_glm_shards.py --model-dir \"$GLM_DEST\" --shard 3"
|
||||
},
|
||||
{
|
||||
"step": 5,
|
||||
"shard_index": 4,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00004-of-00006.gguf",
|
||||
"size_bytes": 49396052864,
|
||||
"size_gb": 49.396,
|
||||
"sha256": "a6a42da6975e29f89866dcde2956e9e50e6ea26635fb5063b74f3973f4f863b6",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00004-of-00006.gguf",
|
||||
"download_command": "curl -L -C - --fail -o \"$GLM_DEST/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00004-of-00006.gguf\" \"https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00004-of-00006.gguf\"",
|
||||
"verify_command": "python scripts/verify_glm_shards.py --model-dir \"$GLM_DEST\" --shard 4"
|
||||
},
|
||||
{
|
||||
"step": 6,
|
||||
"shard_index": 5,
|
||||
"path": "UD-IQ1_S/GLM-5.2-UD-IQ1_S-00005-of-00006.gguf",
|
||||
"size_bytes": 49246275936,
|
||||
"size_gb": 49.246,
|
||||
"sha256": "a4a9851a50db533f21ef824e5d8038f04e6782e7d602d18e5fdd6643f68ccccb",
|
||||
"url": "https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00005-of-00006.gguf",
|
||||
"download_command": "curl -L -C - --fail -o \"$GLM_DEST/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00005-of-00006.gguf\" \"https://huggingface.co/unsloth/GLM-5.2-GGUF/resolve/abc55e72527792c6e77069c99b4cb7de16fa9f23/UD-IQ1_S/GLM-5.2-UD-IQ1_S-00005-of-00006.gguf\"",
|
||||
"verify_command": "python scripts/verify_glm_shards.py --model-dir \"$GLM_DEST\" --shard 5"
|
||||
}
|
||||
],
|
||||
"verdict": "fail"
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
# Maintenance review handoff — distributed GGUF runtime
|
||||
|
||||
Date: 2026-07-14
|
||||
Scope: close the maintenance review, preserve the hard blockers, and hand off the remaining implementation work to the next model.
|
||||
|
||||
## What is complete
|
||||
|
||||
- Completed stories are now recorded in `docs/issues/distributed-gguf-runtime/`.
|
||||
- The PRD and milestone docs were updated to reflect the closed set and the blocked set.
|
||||
- The DGR-018 preflight scripts were preserved at commit `a0f28b5`.
|
||||
- The current feature line has delivered DGR-001 through DGR-006 and DGR-017.
|
||||
|
||||
## Hard / unsolved issues for later
|
||||
|
||||
### 1) DGR-018 requires hardware we do not have
|
||||
|
||||
DGR-018 is blocked because the whole-model GLM-5.2 UD-IQ1_S oracle requires:
|
||||
|
||||
- a **256-GiB-class host**,
|
||||
- at least **224 GiB runtime-accessible memory**,
|
||||
- at least **250 GB free storage on one filesystem outside `/home`**.
|
||||
|
||||
The current development host reports only **124.9 GiB MemTotal** and has no eligible filesystem with 250 GB free.
|
||||
The authoritative blocker evidence is in `evidence/DGR-018/BLOCKED.md` and `evidence/DGR-018/preflight.json`.
|
||||
|
||||
### 2) DGR-019 and DGR-020 are transitively blocked
|
||||
|
||||
- **DGR-019** needs the DGR-018 oracle for parity certification.
|
||||
- **DGR-020** needs DGR-018 and DGR-019, plus enough physical consumer nodes that no single node can admit the whole recipe.
|
||||
|
||||
No smaller model may be substituted for these stories.
|
||||
|
||||
### 3) The remainder of the graph stays blocked unless replanned
|
||||
|
||||
The current graph makes **DGR-007 depend on DGR-019**, which means:
|
||||
|
||||
- DGR-007 through DGR-016 are also blocked transitively.
|
||||
- Unblocking the dense pipeline without the 256-GiB host would require an explicit replanning decision to relax the DGR-007 → DGR-019 dependency.
|
||||
- That replanning decision has **not** been made.
|
||||
|
||||
### 4) Maintenance-only tasks should stay separate from feature implementation
|
||||
|
||||
The review uncovered that the codebase now has a clean closed-story split, but further work should avoid mixing:
|
||||
|
||||
- maintenance cleanup,
|
||||
- blocked-hardware preparation,
|
||||
- and actual distributed GLM implementation.
|
||||
|
||||
The next model should treat the maintenance pass as closed and only pick up real implementation work that is not hardware-blocked.
|
||||
|
||||
## Recommended next move
|
||||
|
||||
Use the next model to continue on the **non-blocked implementation queue** only.
|
||||
Priority candidates are whatever is still actionable without the GLM oracle host; if a story depends on DGR-018, keep it deferred.
|
||||
|
||||
## Reference files
|
||||
|
||||
- `docs/issues/distributed-gguf-runtime/README.md`
|
||||
- `.scratch/distributed-gguf-runtime/PRD.md`
|
||||
- `.scratch/distributed-gguf-runtime/milestones.md`
|
||||
- `.scratch/distributed-gguf-runtime/evidence/DGR-018/BLOCKED.md`
|
||||
- `.scratch/distributed-gguf-runtime/evidence/DGR-018/preflight.json`
|
||||
@@ -1,6 +1,15 @@
|
||||
# 18 — Certify whole-model GLM-5.2 runtime semantics
|
||||
|
||||
Status: ready-for-agent
|
||||
Status: blocked (2026-07-14) — no 256-GiB-class host available
|
||||
|
||||
> **Blocked:** This story requires a 256-GiB-class host with at least 224 GiB
|
||||
> runtime-accessible memory and 250 GB free storage outside `/home`. The
|
||||
> development host has 124.9 GiB MemTotal and no eligible filesystem (largest:
|
||||
> 74.2 GB free). Exact preflight output is preserved in
|
||||
> [evidence/DGR-018/BLOCKED.md](../evidence/DGR-018/BLOCKED.md); preflight
|
||||
> scripts were preserved at commit a0f28b5 (`scripts/glm_whole_model_preflight.py`,
|
||||
> `scripts/verify_glm_shards.py`). Resume by re-running the preflight on a
|
||||
> qualifying host — do not substitute a smaller model.
|
||||
|
||||
## Mandatory fresh-session context
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
# 19 — Implement and certify GLM-5.2 range, DSA, and IndexShare semantics
|
||||
|
||||
Status: ready-for-agent
|
||||
Status: blocked (2026-07-14) — waiting on DGR-018
|
||||
|
||||
> **Blocked:** Depends on DGR-018's whole-model IQ1_S oracle, which is blocked
|
||||
> on a 256-GiB-class host (≥ 224 GiB runtime-accessible memory). See
|
||||
> [evidence/DGR-018/BLOCKED.md](../evidence/DGR-018/BLOCKED.md). Locked
|
||||
> fixture/target parity cannot be certified without that oracle.
|
||||
|
||||
## Mandatory fresh-session context
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
# 20 — Pass real distributed GLM-5.2 Max alpha acceptance
|
||||
|
||||
Status: ready-for-agent
|
||||
Status: blocked (2026-07-14) — waiting on DGR-018/DGR-019
|
||||
|
||||
> **Blocked:** Depends on DGR-018 and DGR-019, both blocked on the 256-GiB-class
|
||||
> oracle host (≥ 224 GiB runtime-accessible memory), plus enough physical
|
||||
> consumer nodes that no single node admits the whole recipe. See
|
||||
> [evidence/DGR-018/BLOCKED.md](../evidence/DGR-018/BLOCKED.md).
|
||||
|
||||
## Mandatory fresh-session context
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ The exact alpha target and immutable acceptance gates are defined in [GLM-5.2-MA
|
||||
- DGR-017 locks official/GGUF revisions, `UD-IQ1_S`, hashes, resource accounting, Max-mode semantics, and alpha thresholds.
|
||||
- DGR-003 builds exact recipe identity on DGR-002 and DGR-017.
|
||||
- DGR-004 creates the reproducible pinned llama.cpp boundary after stock GLM behavior is measured.
|
||||
- DGR-018 certifies one whole-model `UD-IQ1_S` oracle with real MoE, DSA, IndexShare, KV, and `reasoning_effort=max` semantics.
|
||||
- DGR-018 certifies one whole-model `UD-IQ1_S` oracle with real MoE, DSA, IndexShare, KV, and `reasoning_effort=max` semantics. **Blocked (2026-07-14):** requires a 256-GiB-class host (≥ 224 GiB runtime-accessible memory); see [evidence/DGR-018/BLOCKED.md](evidence/DGR-018/BLOCKED.md). DGR-019 and DGR-020 are blocked transitively.
|
||||
|
||||
## Gate B — minimal native execution seam
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
],
|
||||
"priority": 1,
|
||||
"passes": true,
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/01-lock-the-safetensors-versus-gguf-performance-contract.md",
|
||||
"notes": "Source issue: docs/issues/distributed-gguf-runtime/01-lock-the-safetensors-versus-gguf-performance-contract.md (moved on close, MAINT-003)",
|
||||
"dependsOn": []
|
||||
},
|
||||
{
|
||||
@@ -55,7 +55,7 @@
|
||||
],
|
||||
"priority": 2,
|
||||
"passes": true,
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/02-adopt-the-versioned-grpc-shard-protocol.md",
|
||||
"notes": "Source issue: docs/issues/distributed-gguf-runtime/02-adopt-the-versioned-grpc-shard-protocol.md (moved on close, MAINT-003)",
|
||||
"dependsOn": []
|
||||
},
|
||||
{
|
||||
@@ -81,7 +81,7 @@
|
||||
],
|
||||
"priority": 4,
|
||||
"passes": true,
|
||||
"notes": "DGR-003-emission: native loaded-artifact adapter derives exact identity from immutable GGUF/runtime inputs, doctor emits it only for that adapter, and SessionOpen fails closed before acceptance. Exact identities remain tracker-uncertified and dark until a real distributed forward is certified.",
|
||||
"notes": "DGR-003-emission: native loaded-artifact adapter derives exact identity from immutable GGUF/runtime inputs, doctor emits it only for that adapter, and SessionOpen fails closed before acceptance. Exact identities remain tracker-uncertified and dark until a real distributed forward is certified. (moved on close, MAINT-003)",
|
||||
"dependsOn": [
|
||||
"DGR-002",
|
||||
"DGR-017"
|
||||
@@ -113,7 +113,7 @@
|
||||
],
|
||||
"priority": 5,
|
||||
"passes": true,
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/04-create-the-reproducible-pinned-llama-cpp-patch-stack.md",
|
||||
"notes": "Source issue: docs/issues/distributed-gguf-runtime/04-create-the-reproducible-pinned-llama-cpp-patch-stack.md (moved on close, MAINT-003)",
|
||||
"dependsOn": [
|
||||
"DGR-001",
|
||||
"DGR-017"
|
||||
@@ -144,7 +144,7 @@
|
||||
],
|
||||
"priority": 6,
|
||||
"passes": true,
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/05-implement-dense-llama-range-aware-gguf-ownership.md",
|
||||
"notes": "Source issue: docs/issues/distributed-gguf-runtime/05-implement-dense-llama-range-aware-gguf-ownership.md (moved on close, MAINT-003)",
|
||||
"dependsOn": [
|
||||
"DGR-003",
|
||||
"DGR-004"
|
||||
@@ -178,7 +178,7 @@
|
||||
],
|
||||
"priority": 7,
|
||||
"passes": true,
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/06-implement-architecture-defined-boundary-input-output.md",
|
||||
"notes": "Source issue: docs/issues/distributed-gguf-runtime/06-implement-architecture-defined-boundary-input-output.md (moved on close, MAINT-003)",
|
||||
"dependsOn": [
|
||||
"DGR-002",
|
||||
"DGR-005"
|
||||
@@ -538,7 +538,7 @@
|
||||
],
|
||||
"priority": 3,
|
||||
"passes": true,
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/17-lock-glm-5-2-max-target-and-alpha-contract.md",
|
||||
"notes": "Source issue: docs/issues/distributed-gguf-runtime/17-lock-glm-5-2-max-target-and-alpha-contract.md (moved on close, MAINT-003)",
|
||||
"dependsOn": [
|
||||
"DGR-001",
|
||||
"DGR-002"
|
||||
@@ -570,7 +570,7 @@
|
||||
],
|
||||
"priority": 8,
|
||||
"passes": false,
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/18-certify-whole-model-glm-5-2-runtime-semantics.md",
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/18-certify-whole-model-glm-5-2-runtime-semantics.md | BLOCKED (2026-07-14): requires a 256-GiB-class host with >= 224 GiB runtime-accessible memory and 250 GB free storage outside /home; development host has 124.9 GiB MemTotal and no eligible filesystem. Exact preflight output: evidence/DGR-018/BLOCKED.md. Preflight scripts preserved at commit a0f28b5.",
|
||||
"dependsOn": [
|
||||
"DGR-003",
|
||||
"DGR-004",
|
||||
@@ -603,7 +603,7 @@
|
||||
],
|
||||
"priority": 9,
|
||||
"passes": false,
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/19-implement-and-certify-glm-5-2-range-dsa-indexshare.md",
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/19-implement-and-certify-glm-5-2-range-dsa-indexshare.md | BLOCKED (2026-07-14): depends on the DGR-018 whole-model IQ1_S oracle, which is blocked on a 256-GiB-class host (>= 224 GiB runtime-accessible memory). See evidence/DGR-018/BLOCKED.md.",
|
||||
"dependsOn": [
|
||||
"DGR-005",
|
||||
"DGR-006",
|
||||
@@ -639,7 +639,7 @@
|
||||
],
|
||||
"priority": 16,
|
||||
"passes": false,
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/20-pass-real-distributed-glm-5-2-max-alpha.md",
|
||||
"notes": "Source issue: .scratch/distributed-gguf-runtime/issues/20-pass-real-distributed-glm-5-2-max-alpha.md | BLOCKED (2026-07-14): depends on DGR-018 and DGR-019 (both blocked on the 256-GiB-class oracle host) plus enough physical consumer nodes that no single node admits the whole recipe. See evidence/DGR-018/BLOCKED.md.",
|
||||
"dependsOn": [
|
||||
"DGR-007",
|
||||
"DGR-008",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 04 — Chain: DGR-005 + DGR-003-emission + anchor
|
||||
|
||||
Status: in-progress
|
||||
Status: done
|
||||
|
||||
## Mandatory fresh-session context
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 05 — Implement dense-Llama range-aware GGUF ownership
|
||||
|
||||
Status: ready-for-agent
|
||||
Status: done
|
||||
|
||||
## Mandatory fresh-session context
|
||||
|
||||
26
docs/issues/distributed-gguf-runtime/README.md
Normal file
26
docs/issues/distributed-gguf-runtime/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Distributed GGUF runtime — closed issues
|
||||
|
||||
Completed stories from the `distributed-gguf-runtime` feature
|
||||
(`.scratch/distributed-gguf-runtime/`), moved here on 2026-07-14 (MAINT-003).
|
||||
Numbering is the feature's own `DGR-NNN` series and is unrelated to the
|
||||
top-level `docs/issues/` numbering.
|
||||
|
||||
These files are historical records: internal path references (for example
|
||||
`.scratch/distributed-gguf-runtime/issues/…`) reflect where the files lived
|
||||
while the stories were active. Authoritative completion status is
|
||||
`passes: true` in `.scratch/distributed-gguf-runtime/prd.json`, backed by the
|
||||
signed evidence in `.scratch/distributed-gguf-runtime/evidence/DGR-*/`.
|
||||
|
||||
| Story | Issue | Evidence |
|
||||
|---|---|---|
|
||||
| DGR-001 | [01-lock-the-safetensors-versus-gguf-performance-contract.md](01-lock-the-safetensors-versus-gguf-performance-contract.md) | `evidence/DGR-001/` |
|
||||
| DGR-002 | [02-adopt-the-versioned-grpc-shard-protocol.md](02-adopt-the-versioned-grpc-shard-protocol.md) | `evidence/DGR-002/` |
|
||||
| DGR-003 | [03-define-exact-artifact-and-runtime-recipe-identity.md](03-define-exact-artifact-and-runtime-recipe-identity.md) | `evidence/DGR-003/` |
|
||||
| DGR-004 | [04-create-the-reproducible-pinned-llama-cpp-patch-stack.md](04-create-the-reproducible-pinned-llama-cpp-patch-stack.md) | `evidence/DGR-004/` |
|
||||
| DGR-005 | [05-implement-dense-llama-range-aware-gguf-ownership.md](05-implement-dense-llama-range-aware-gguf-ownership.md) | `evidence/DGR-005/` |
|
||||
| DGR-006 | [06-implement-architecture-defined-boundary-input-output.md](06-implement-architecture-defined-boundary-input-output.md) | `evidence/DGR-006/` |
|
||||
| DGR-017 | [17-lock-glm-5-2-max-target-and-alpha-contract.md](17-lock-glm-5-2-max-target-and-alpha-contract.md) | `evidence/DGR-017/` |
|
||||
|
||||
Open and blocked stories remain in `.scratch/distributed-gguf-runtime/issues/`.
|
||||
DGR-018, DGR-019, and DGR-020 are blocked on a 256-GiB-class host — see
|
||||
`.scratch/distributed-gguf-runtime/evidence/DGR-018/BLOCKED.md`.
|
||||
@@ -3,7 +3,6 @@
|
||||
import http.server
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from collections import Counter
|
||||
from dataclasses import dataclass
|
||||
import threading
|
||||
@@ -62,7 +61,7 @@ class _GatewayHTTPServer(http.server.HTTPServer):
|
||||
|
||||
|
||||
class _GatewayHandler(http.server.BaseHTTPRequestHandler):
|
||||
def log_message(self, fmt, *args): # noqa: suppress request logs in tests
|
||||
def log_message(self, fmt, *args): # suppress request logs in tests
|
||||
pass
|
||||
|
||||
def do_GET(self):
|
||||
|
||||
@@ -144,7 +144,7 @@ def _cmd_default(args) -> int:
|
||||
print("\nSetup cancelled.")
|
||||
return 1
|
||||
save_config(cfg)
|
||||
print(f"\nConfig saved to ~/.config/meshnet/config.json\n")
|
||||
print("\nConfig saved to ~/.config/meshnet/config.json\n")
|
||||
|
||||
# Apply CLI overrides on top of saved config
|
||||
overrides: dict = {}
|
||||
@@ -198,7 +198,7 @@ def _cmd_default(args) -> int:
|
||||
|
||||
def _cmd_models(args) -> int:
|
||||
"""List curated models (with optional HF Hub browse)."""
|
||||
from .wizard import print_models_table, _browse_hf_interactive
|
||||
from .wizard import print_models_table
|
||||
|
||||
if args.browse:
|
||||
from .model_catalog import browse_hf_hub
|
||||
|
||||
@@ -5,7 +5,6 @@ from __future__ import annotations
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from collections import deque
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -114,7 +113,7 @@ def run_dashboard(node, config: dict, start_time: float) -> None:
|
||||
return
|
||||
|
||||
try:
|
||||
from rich.live import Live # type: ignore[import]
|
||||
from rich.live import Live # type: ignore[import] # noqa: F401
|
||||
|
||||
_run_rich_dashboard(node, config, start_time)
|
||||
except ImportError:
|
||||
@@ -126,7 +125,6 @@ def _build_rich_renderable(
|
||||
):
|
||||
from rich.table import Table # type: ignore[import]
|
||||
from rich.panel import Panel # type: ignore[import]
|
||||
from rich.columns import Columns # type: ignore[import]
|
||||
from rich.text import Text # type: ignore[import]
|
||||
|
||||
uptime = time.monotonic() - start_time
|
||||
@@ -178,8 +176,8 @@ def _build_rich_renderable(
|
||||
f"Tokens/sec {tps_bar} {tps:.1f} t/s (EMA)",
|
||||
f"Requests {req_count:,} served",
|
||||
f"Success {stats['success_rate']:.1f}% failed {stats['failed_requests']:,} queue {stats['queue_depth']}",
|
||||
f"Peers 0 connected (gossip: US-017)",
|
||||
f"TAI earned 0.00 TAI (payments: US-006)",
|
||||
"Peers 0 connected (gossip: US-017)",
|
||||
"TAI earned 0.00 TAI (payments: US-006)",
|
||||
f"Uptime {_format_uptime(uptime)}",
|
||||
"",
|
||||
"[q] quit [c] compact view",
|
||||
|
||||
@@ -105,7 +105,7 @@ class _StubHTTPServer(http.server.HTTPServer):
|
||||
|
||||
|
||||
class _StubHandler(http.server.BaseHTTPRequestHandler):
|
||||
def log_message(self, fmt, *args): # noqa: suppress request logs in tests
|
||||
def log_message(self, fmt, *args): # suppress request logs in tests
|
||||
pass
|
||||
|
||||
def do_POST(self):
|
||||
|
||||
@@ -19,7 +19,6 @@ from .model_backend import (
|
||||
InsufficientVRAMError,
|
||||
KVCacheMiss,
|
||||
MissingModelDependencyError,
|
||||
Quantization,
|
||||
TailTokenResult,
|
||||
TorchModelShard,
|
||||
_tensor_from_bfloat16_bytes,
|
||||
@@ -46,7 +45,7 @@ class _DirectRequestUncertainError(ConnectionError):
|
||||
"""A direct request may have reached the downstream node but did not finish."""
|
||||
|
||||
|
||||
from .server import (
|
||||
from .server import ( # noqa: E402
|
||||
_WIRE_VERSION,
|
||||
_parse_shape,
|
||||
_validate_activation_body,
|
||||
@@ -399,7 +398,7 @@ class _TorchHandler(http.server.BaseHTTPRequestHandler):
|
||||
# Finite responses below provide Content-Length; streams are chunked.
|
||||
protocol_version = "HTTP/1.1"
|
||||
|
||||
def log_message(self, fmt, *args): # noqa: suppress request logs in tests
|
||||
def log_message(self, fmt, *args): # suppress request logs in tests
|
||||
pass
|
||||
|
||||
def _request_id(self) -> str:
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
@@ -7,7 +7,6 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import socket
|
||||
import threading
|
||||
from typing import Callable
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import hashlib
|
||||
import ipaddress
|
||||
import json
|
||||
import os
|
||||
import socket
|
||||
import ssl
|
||||
|
||||
@@ -4,7 +4,6 @@ from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ import threading
|
||||
import time
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any, Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -26,7 +26,7 @@ import random
|
||||
import sqlite3
|
||||
import threading
|
||||
import time
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Iterable
|
||||
|
||||
|
||||
|
||||
@@ -53,10 +53,6 @@ from typing import Any
|
||||
from .accounts import DEFAULT_ACCOUNTS_DB_PATH, AccountStore
|
||||
from .auth import is_validator_token, sign_hive_request, verify_hive_request
|
||||
from .capability import (
|
||||
DEFAULT_POLICY as DEFAULT_CAPABILITY_POLICY,
|
||||
POLICY_COMPAT,
|
||||
POLICY_ENFORCE,
|
||||
STATE_ABSENT,
|
||||
STATE_ADMITTED,
|
||||
STATE_MODEL_MISMATCH,
|
||||
STATE_SHARD_MISMATCH,
|
||||
@@ -69,7 +65,7 @@ from .capability import (
|
||||
)
|
||||
from .wallet_proof import binding_message, verify_wallet_signature
|
||||
from .billing import DEFAULT_BILLING_DB_PATH, BillingLedger
|
||||
from .calibration import DEFAULT_CALIBRATION_DB_PATH, ToplocCalibrationStore
|
||||
from .calibration import ToplocCalibrationStore
|
||||
from .hf_pricing import DEFAULT_HF_PRICING_LOG_DB_PATH, HfPricingLog, refresh_preset_price
|
||||
from .gossip import NodeGossip
|
||||
from .logging_setup import tracker_logger
|
||||
@@ -2566,8 +2562,8 @@ def _estimate_prompt_tokens(body: dict) -> int | None:
|
||||
|
||||
|
||||
def _requested_completion_token_limit(body: dict) -> int | None:
|
||||
for field in ("max_completion_tokens", "max_tokens"):
|
||||
value = body.get(field)
|
||||
for key in ("max_completion_tokens", "max_tokens"):
|
||||
value = body.get(key)
|
||||
if isinstance(value, bool):
|
||||
return None
|
||||
if isinstance(value, (int, float)):
|
||||
@@ -2948,7 +2944,7 @@ class _TrackerHTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
|
||||
|
||||
|
||||
class _TrackerHandler(http.server.BaseHTTPRequestHandler):
|
||||
def log_message(self, fmt, *args): # noqa: suppress request logs in tests
|
||||
def log_message(self, fmt, *args): # suppress request logs in tests
|
||||
pass
|
||||
|
||||
def _send_json(self, status: int, data: dict, headers: dict[str, str] | None = None) -> None:
|
||||
@@ -7069,10 +7065,6 @@ class TrackerServer:
|
||||
shard_end = int(payload["shard_end"]) if payload.get("shard_end") is not None else None
|
||||
except (TypeError, ValueError):
|
||||
return
|
||||
try:
|
||||
friendly_name = _normalize_friendly_name(payload.get("friendly_name"))
|
||||
except ValueError:
|
||||
friendly_name = None
|
||||
# The replicated payload is the raw registration body, so the follower can
|
||||
# resolve precision exactly as the leader did -- including telling a legacy
|
||||
# absent `quantization` from a declared one. Dropping these fields here
|
||||
|
||||
@@ -545,6 +545,8 @@ def _post_json(url: str, payload: dict, timeout: float = 5.0) -> dict:
|
||||
__all__ = [
|
||||
"ToplocAuditConfig",
|
||||
"ToplocProofClaim",
|
||||
"ToplocVerificationResult",
|
||||
"verify_activation_proofs_detailed",
|
||||
"ValidatorProcess",
|
||||
"AdaptiveAuditSampler",
|
||||
"AuditRateConfig",
|
||||
|
||||
@@ -14,6 +14,11 @@ dev = ["pytest>=8", "openai>=1", "langchain-openai>=0.1", "cryptography>=41"]
|
||||
[tool.setuptools]
|
||||
packages = []
|
||||
|
||||
[tool.ruff]
|
||||
# Protobuf/gRPC stubs are regenerated by scripts/generate_native_protocol.py;
|
||||
# linting them would drift the checked-in files from the generator's output.
|
||||
extend-exclude = ["packages/node/meshnet_node/native_protocol/generated"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
markers = [
|
||||
|
||||
@@ -5,8 +5,7 @@ from __future__ import annotations
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -277,7 +276,6 @@ def test_relay_server_peer_list_grows_on_connect():
|
||||
def test_relay_circuit_relay_proxies_message():
|
||||
"A node behind NAT (client_a) receives a message via circuit relay from client_b.\n\nTags: gossip, network, relay"
|
||||
|
||||
import websockets.sync.client # type: ignore[import]
|
||||
from meshnet_relay.server import RelayServer
|
||||
|
||||
relay = RelayServer(host="127.0.0.1", port=0)
|
||||
@@ -755,7 +753,6 @@ def test_node_relay_bridge_reconnects_after_failed_connection(monkeypatch):
|
||||
|
||||
def _start_tracker_and_register(extra_fields: dict) -> dict:
|
||||
"""Helper: start tracker, register node with extra gossip fields, return response."""
|
||||
import http.server
|
||||
import json as _json
|
||||
import urllib.request
|
||||
|
||||
@@ -766,7 +763,7 @@ def _start_tracker_and_register(extra_fields: dict) -> dict:
|
||||
url = f"http://127.0.0.1:{port}"
|
||||
|
||||
payload = {
|
||||
"endpoint": f"http://127.0.0.1:8001",
|
||||
"endpoint": "http://127.0.0.1:8001",
|
||||
"shard_start": 0,
|
||||
"shard_end": 7,
|
||||
"model": "stub-model",
|
||||
|
||||
@@ -5,8 +5,6 @@ from __future__ import annotations
|
||||
import json
|
||||
import socket
|
||||
import sys
|
||||
import types
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
# A fake node server has no real backend to prove capability with; say so
|
||||
@@ -134,7 +132,6 @@ def test_print_models_table_runs_without_error(capsys, monkeypatch):
|
||||
def test_wizard_writes_config_on_happy_path(tmp_path, monkeypatch):
|
||||
"Wizard writes config on happy path\n\nTags: general"
|
||||
from meshnet_node import wizard as wiz
|
||||
from meshnet_node.config import load_config, save_config
|
||||
|
||||
# Fake GPU
|
||||
gpus = [{"index": 0, "name": "RTX 4090", "vram_gb": 24.0, "backend": "cuda"}]
|
||||
@@ -265,7 +262,6 @@ def test_config_command_no_config_exits_1(tmp_path, monkeypatch):
|
||||
|
||||
def test_config_command_prints_saved_config(tmp_path, monkeypatch, capsys):
|
||||
"Config command prints saved config\n\nTags: general"
|
||||
from meshnet_node import config as cfg_mod
|
||||
from meshnet_node.config import save_config
|
||||
from meshnet_node.cli import main
|
||||
|
||||
@@ -309,7 +305,6 @@ def test_detect_num_layers_returns_none_on_error(monkeypatch):
|
||||
def test_startup_auto_detects_shard_range(monkeypatch, tmp_path):
|
||||
"When shard_start/end are None, startup reads layer count from catalog.\n\nTags: general"
|
||||
from meshnet_node import startup as su
|
||||
from meshnet_node.model_catalog import detect_num_layers
|
||||
|
||||
calls = []
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ def test_streaming_end_to_end_http(two_node_setup):
|
||||
assert "text/event-stream" in content_type
|
||||
raw = resp.read().decode()
|
||||
|
||||
data_lines = [l for l in raw.strip().splitlines() if l.startswith("data: ")]
|
||||
data_lines = [line for line in raw.strip().splitlines() if line.startswith("data: ")]
|
||||
assert data_lines, "No SSE data lines found"
|
||||
assert data_lines[-1] == "data: [DONE]"
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import urllib.request
|
||||
import pytest
|
||||
|
||||
from meshnet_node.model_backend import (
|
||||
InsufficientVRAMError,
|
||||
PartialModelLoadUnsupported,
|
||||
KVCacheMiss,
|
||||
TensorPayload,
|
||||
|
||||
@@ -5,9 +5,7 @@ before the transaction is sent, unconfirmed batches resent by settlement id
|
||||
(never double-paying), banned wallets skipped, history queryable over HTTP.
|
||||
"""
|
||||
|
||||
import json
|
||||
import time
|
||||
import urllib.request
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -68,7 +66,7 @@ def test_threshold_triggers_payout_and_zeroes_pending():
|
||||
ledger.charge_request("client", MODEL, 1000, [("wallet-a", 12)]) # 0.018 pending
|
||||
treasury = _FakePayoutTreasury()
|
||||
tracker = _make_tracker(ledger, treasury, threshold=0.01)
|
||||
port = tracker.start()
|
||||
tracker.start()
|
||||
try:
|
||||
assert _wait_for(lambda: treasury.batches)
|
||||
assert treasury.batches[0] == [("wallet-a", pytest.approx(0.018))]
|
||||
|
||||
@@ -157,7 +157,7 @@ def test_registration_on_follower_visible_on_all_nodes(three_tracker_cluster):
|
||||
_wait_until_follower_knows_leader(follower, timeout=2.0)
|
||||
|
||||
# Register via a follower
|
||||
node_id = _register_node(follower, port_hint=19999)
|
||||
_register_node(follower, port_hint=19999)
|
||||
|
||||
# Allow replication to propagate (Raft heartbeat interval is 50ms)
|
||||
time.sleep(0.5)
|
||||
@@ -223,7 +223,7 @@ def test_registration_on_leader_visible_to_all(three_tracker_cluster):
|
||||
urls = list(urls)
|
||||
|
||||
leader_url, followers = _wait_for_leader(urls, timeout=1.0)
|
||||
node_id = _register_node(leader_url, port_hint=19996)
|
||||
_register_node(leader_url, port_hint=19996)
|
||||
|
||||
# Allow Raft heartbeat to replicate the entry
|
||||
time.sleep(0.3)
|
||||
|
||||
@@ -19,7 +19,6 @@ from meshnet_tracker.server import (
|
||||
TrackerServer,
|
||||
_NodeEntry,
|
||||
_available_quantizations,
|
||||
_memory_pool_map,
|
||||
_rebalance_all_locked,
|
||||
_registration_ban_error,
|
||||
_scale_demanded_models_locked,
|
||||
@@ -1448,7 +1447,7 @@ def test_tracker_pool_join_adds_redundant_copy_without_splitting_incumbent():
|
||||
"vram_bytes": 10_000, "ram_bytes": 10_000, "quantizations": ["bfloat16"],
|
||||
"benchmark_tokens_per_sec": 1.0, "hardware_profile": {}, "score": 1.0},
|
||||
)
|
||||
second = _post_json(
|
||||
_post_json(
|
||||
f"http://127.0.0.1:{tracker_port}/v1/nodes/register",
|
||||
{"endpoint": "http://127.0.0.1:9016", "model": "tiny-model",
|
||||
"vram_bytes": 10_000, "ram_bytes": 10_000, "quantizations": ["bfloat16"],
|
||||
|
||||
Reference in New Issue
Block a user