keep-npu 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. keep_npu-1.0.0/LICENSE +21 -0
  2. keep_npu-1.0.0/MANIFEST.in +2 -0
  3. keep_npu-1.0.0/PKG-INFO +146 -0
  4. keep_npu-1.0.0/README.md +113 -0
  5. keep_npu-1.0.0/docs/compatibility.md +34 -0
  6. keep_npu-1.0.0/docs/releasing.md +31 -0
  7. keep_npu-1.0.0/docs/superpowers/plans/2026-07-21-keepgpu-parity.md +162 -0
  8. keep_npu-1.0.0/docs/superpowers/specs/2026-07-21-keepgpu-parity-design.md +238 -0
  9. keep_npu-1.0.0/docs/validation/ascend-remote-results.md +96 -0
  10. keep_npu-1.0.0/pyproject.toml +147 -0
  11. keep_npu-1.0.0/setup.cfg +4 -0
  12. keep_npu-1.0.0/src/keep_npu/__init__.py +4 -0
  13. keep_npu-1.0.0/src/keep_npu/cli.py +1718 -0
  14. keep_npu-1.0.0/src/keep_npu/global_npu_controller/__init__.py +4 -0
  15. keep_npu-1.0.0/src/keep_npu/global_npu_controller/global_npu_controller.py +132 -0
  16. keep_npu-1.0.0/src/keep_npu/legacy.py +239 -0
  17. keep_npu-1.0.0/src/keep_npu/mcp/__init__.py +0 -0
  18. keep_npu-1.0.0/src/keep_npu/mcp/server.py +1839 -0
  19. keep_npu-1.0.0/src/keep_npu/mcp/static/assets/dashboard.js +8 -0
  20. keep_npu-1.0.0/src/keep_npu/mcp/static/assets/index.css +1 -0
  21. keep_npu-1.0.0/src/keep_npu/mcp/static/index.html +13 -0
  22. keep_npu-1.0.0/src/keep_npu/single_npu_controller/__init__.py +6 -0
  23. keep_npu-1.0.0/src/keep_npu/single_npu_controller/ascend_npu_controller.py +226 -0
  24. keep_npu-1.0.0/src/keep_npu/single_npu_controller/base_npu_controller.py +23 -0
  25. keep_npu-1.0.0/src/keep_npu/utilities/__init__.py +3 -0
  26. keep_npu-1.0.0/src/keep_npu/utilities/endpoint_validation.py +71 -0
  27. keep_npu-1.0.0/src/keep_npu/utilities/humanized_input.py +134 -0
  28. keep_npu-1.0.0/src/keep_npu/utilities/json_protocol.py +25 -0
  29. keep_npu-1.0.0/src/keep_npu/utilities/logger.py +103 -0
  30. keep_npu-1.0.0/src/keep_npu/utilities/npu_info.py +202 -0
  31. keep_npu-1.0.0/src/keep_npu/utilities/npu_monitor.py +6 -0
  32. keep_npu-1.0.0/src/keep_npu/utilities/platform_manager.py +70 -0
  33. keep_npu-1.0.0/src/keep_npu/utilities/session_config.py +162 -0
  34. keep_npu-1.0.0/src/keep_npu.egg-info/PKG-INFO +146 -0
  35. keep_npu-1.0.0/src/keep_npu.egg-info/SOURCES.txt +37 -0
  36. keep_npu-1.0.0/src/keep_npu.egg-info/dependency_links.txt +1 -0
  37. keep_npu-1.0.0/src/keep_npu.egg-info/entry_points.txt +4 -0
  38. keep_npu-1.0.0/src/keep_npu.egg-info/requires.txt +14 -0
  39. keep_npu-1.0.0/src/keep_npu.egg-info/top_level.txt +1 -0
keep_npu-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Wang Siyuan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ prune tests
2
+ recursive-include docs *.md
@@ -0,0 +1,146 @@
1
+ Metadata-Version: 2.4
2
+ Name: keep-npu
3
+ Version: 1.0.0
4
+ Summary: KeepNPU is a polite NPU keeper with CLI, service, and MCP interfaces
5
+ Author: Peter Zheng
6
+ Maintainer: Peter Zheng
7
+ License-Expression: MIT
8
+ Project-URL: bugs, https://github.com/pzheng460/keep-npu/issues
9
+ Project-URL: changelog, https://github.com/pzheng460/keep-npu/releases
10
+ Project-URL: homepage, https://github.com/pzheng460/keep-npu
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Requires-Python: <3.14,>=3.9
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: typer
21
+ Requires-Dist: rich>=13.8.0
22
+ Provides-Extra: dev
23
+ Requires-Dist: coverage; extra == "dev"
24
+ Requires-Dist: mypy; extra == "dev"
25
+ Requires-Dist: pytest; extra == "dev"
26
+ Requires-Dist: ruff; extra == "dev"
27
+ Requires-Dist: black; extra == "dev"
28
+ Requires-Dist: pre-commit; extra == "dev"
29
+ Requires-Dist: bump-my-version; extra == "dev"
30
+ Requires-Dist: setuptools<82,>=77; extra == "dev"
31
+ Provides-Extra: ascend
32
+ Dynamic: license-file
33
+
34
+ # KeepNPU
35
+
36
+ KeepNPU is a small, polite Huawei Ascend NPU keeper for shared machines. It
37
+ matches KeepGPU's CLI, service, REST/JSON-RPC, MCP, and dashboard workflows,
38
+ using `torch_npu` and `npu-smi` for Ascend devices.
39
+
40
+ It allocates only when utilization backoff permits, keeps the requested device
41
+ memory signal lightweight, and releases cleanly on exit.
42
+
43
+ ## Requirements
44
+
45
+ - Python 3.9–3.13
46
+ - Huawei Ascend driver and CANN runtime
47
+ - A mutually compatible PyTorch and `torch_npu` installation
48
+
49
+ Load the CANN environment before using KeepNPU when your system does not do so
50
+ automatically:
51
+
52
+ ```console
53
+ source /usr/local/Ascend/ascend-toolkit/latest/bin/setenv.bash
54
+ ```
55
+
56
+ ## Install
57
+
58
+ ```console
59
+ python -m pip install keep-npu
60
+ ```
61
+
62
+ `torch` and `torch_npu` are deliberately not installed as package dependencies:
63
+ their versions must match the server's CANN and driver stack.
64
+
65
+ To install the latest unreleased revision directly from GitHub:
66
+
67
+ ```console
68
+ python -m pip install 'keep-npu @ git+https://github.com/pzheng460/keep-npu.git'
69
+ ```
70
+
71
+ ## Blocking mode
72
+
73
+ Keep all visible NPUs, or select torch-visible ordinals with `--npu-ids`:
74
+
75
+ ```console
76
+ keep-npu --vram 1GiB --interval 60
77
+ keep-npu --npu-ids 0,2 --vram 512MiB --interval 30
78
+ ```
79
+
80
+ Press `Ctrl+C` to release memory. The default utilization threshold is 25%;
81
+ KeepNPU backs off while a device is busier than that or telemetry is unknown.
82
+ Use `--busy-threshold -1` only when you intentionally want to disable backoff.
83
+
84
+ ## Service and dashboard
85
+
86
+ Run the local HTTP service in the foreground:
87
+
88
+ ```console
89
+ keep-npu serve --host 127.0.0.1 --port 8765
90
+ ```
91
+
92
+ Open `http://127.0.0.1:8765/` for the dashboard. Non-blocking CLI workflows use
93
+ the same service and auto-start it on localhost by default:
94
+
95
+ ```console
96
+ keep-npu list-npus
97
+ keep-npu start --npu-ids 0 --vram 1GiB --interval 60
98
+ keep-npu status
99
+ keep-npu stop --job-id JOB_ID
100
+ keep-npu stop --all
101
+ keep-npu service-stop
102
+ ```
103
+
104
+ The service exposes `GET /health`, `GET /api/npus`, and session CRUD under
105
+ `/api/sessions`. JSON-RPC is available at the exact `/rpc` endpoint, including
106
+ MCP-shaped `tools/list` and `tools/call` messages. As in KeepGPU 1.0, HTTP mode
107
+ is not a Streamable HTTP MCP endpoint; standards-based MCP transport is stdio.
108
+
109
+ ## MCP server
110
+
111
+ For a local MCP client using stdio:
112
+
113
+ ```console
114
+ keep-npu-mcp-server --mode stdio
115
+ ```
116
+
117
+ For HTTP transport:
118
+
119
+ ```console
120
+ keep-npu-mcp-server --mode http --host 127.0.0.1 --port 8765
121
+ ```
122
+
123
+ The MCP tools are `start_keep`, `stop_keep`, `status`, and `list_npus`.
124
+
125
+ ## Ascend device semantics
126
+
127
+ `--npu-ids` always addresses the visible ordinal used by `torch.npu`, after
128
+ `ASCEND_RT_VISIBLE_DEVICES` filtering. `list-npus` additionally reports the
129
+ physical ID when it can be derived safely. Memory comes from `torch.npu` with
130
+ best-effort `npu-smi` telemetry; unavailable values are returned as `null`
131
+ instead of being guessed.
132
+
133
+ See [KeepGPU compatibility](https://github.com/pzheng460/keep-npu/blob/main/docs/compatibility.md)
134
+ for the exact public-name mapping and intentional Ascend differences.
135
+
136
+ ## Development
137
+
138
+ ```console
139
+ python -m pip install -e '.[dev]'
140
+ PYTHONPATH=src python -m pytest
141
+ cd web/dashboard && npm ci && npm test -- --run && npm run build
142
+ ```
143
+
144
+ Hardware tests use the `ascend` pytest marker and conservative memory sizes.
145
+ The original standalone `keep_npu_alive.py` entry point remains available for
146
+ backward compatibility.
@@ -0,0 +1,113 @@
1
+ # KeepNPU
2
+
3
+ KeepNPU is a small, polite Huawei Ascend NPU keeper for shared machines. It
4
+ matches KeepGPU's CLI, service, REST/JSON-RPC, MCP, and dashboard workflows,
5
+ using `torch_npu` and `npu-smi` for Ascend devices.
6
+
7
+ It allocates only when utilization backoff permits, keeps the requested device
8
+ memory signal lightweight, and releases cleanly on exit.
9
+
10
+ ## Requirements
11
+
12
+ - Python 3.9–3.13
13
+ - Huawei Ascend driver and CANN runtime
14
+ - A mutually compatible PyTorch and `torch_npu` installation
15
+
16
+ Load the CANN environment before using KeepNPU when your system does not do so
17
+ automatically:
18
+
19
+ ```console
20
+ source /usr/local/Ascend/ascend-toolkit/latest/bin/setenv.bash
21
+ ```
22
+
23
+ ## Install
24
+
25
+ ```console
26
+ python -m pip install keep-npu
27
+ ```
28
+
29
+ `torch` and `torch_npu` are deliberately not installed as package dependencies:
30
+ their versions must match the server's CANN and driver stack.
31
+
32
+ To install the latest unreleased revision directly from GitHub:
33
+
34
+ ```console
35
+ python -m pip install 'keep-npu @ git+https://github.com/pzheng460/keep-npu.git'
36
+ ```
37
+
38
+ ## Blocking mode
39
+
40
+ Keep all visible NPUs, or select torch-visible ordinals with `--npu-ids`:
41
+
42
+ ```console
43
+ keep-npu --vram 1GiB --interval 60
44
+ keep-npu --npu-ids 0,2 --vram 512MiB --interval 30
45
+ ```
46
+
47
+ Press `Ctrl+C` to release memory. The default utilization threshold is 25%;
48
+ KeepNPU backs off while a device is busier than that or telemetry is unknown.
49
+ Use `--busy-threshold -1` only when you intentionally want to disable backoff.
50
+
51
+ ## Service and dashboard
52
+
53
+ Run the local HTTP service in the foreground:
54
+
55
+ ```console
56
+ keep-npu serve --host 127.0.0.1 --port 8765
57
+ ```
58
+
59
+ Open `http://127.0.0.1:8765/` for the dashboard. Non-blocking CLI workflows use
60
+ the same service and auto-start it on localhost by default:
61
+
62
+ ```console
63
+ keep-npu list-npus
64
+ keep-npu start --npu-ids 0 --vram 1GiB --interval 60
65
+ keep-npu status
66
+ keep-npu stop --job-id JOB_ID
67
+ keep-npu stop --all
68
+ keep-npu service-stop
69
+ ```
70
+
71
+ The service exposes `GET /health`, `GET /api/npus`, and session CRUD under
72
+ `/api/sessions`. JSON-RPC is available at the exact `/rpc` endpoint, including
73
+ MCP-shaped `tools/list` and `tools/call` messages. As in KeepGPU 1.0, HTTP mode
74
+ is not a Streamable HTTP MCP endpoint; standards-based MCP transport is stdio.
75
+
76
+ ## MCP server
77
+
78
+ For a local MCP client using stdio:
79
+
80
+ ```console
81
+ keep-npu-mcp-server --mode stdio
82
+ ```
83
+
84
+ For HTTP transport:
85
+
86
+ ```console
87
+ keep-npu-mcp-server --mode http --host 127.0.0.1 --port 8765
88
+ ```
89
+
90
+ The MCP tools are `start_keep`, `stop_keep`, `status`, and `list_npus`.
91
+
92
+ ## Ascend device semantics
93
+
94
+ `--npu-ids` always addresses the visible ordinal used by `torch.npu`, after
95
+ `ASCEND_RT_VISIBLE_DEVICES` filtering. `list-npus` additionally reports the
96
+ physical ID when it can be derived safely. Memory comes from `torch.npu` with
97
+ best-effort `npu-smi` telemetry; unavailable values are returned as `null`
98
+ instead of being guessed.
99
+
100
+ See [KeepGPU compatibility](https://github.com/pzheng460/keep-npu/blob/main/docs/compatibility.md)
101
+ for the exact public-name mapping and intentional Ascend differences.
102
+
103
+ ## Development
104
+
105
+ ```console
106
+ python -m pip install -e '.[dev]'
107
+ PYTHONPATH=src python -m pytest
108
+ cd web/dashboard && npm ci && npm test -- --run && npm run build
109
+ ```
110
+
111
+ Hardware tests use the `ascend` pytest marker and conservative memory sizes.
112
+ The original standalone `keep_npu_alive.py` entry point remains available for
113
+ backward compatibility.
@@ -0,0 +1,34 @@
1
+ # KeepGPU compatibility
2
+
3
+ KeepNPU 1.0 follows KeepGPU 1.0's interaction model while translating the
4
+ device backend from CUDA/ROCm/MPS to Huawei Ascend.
5
+
6
+ | KeepGPU public contract | KeepNPU equivalent |
7
+ | --- | --- |
8
+ | `keep-gpu` | `keep-npu` |
9
+ | `keep-gpu-mcp-server` | `keep-npu-mcp-server` |
10
+ | `--gpu-ids` | `--npu-ids` |
11
+ | `list-gpus` / `/api/gpus` | `list-npus` / `/api/npus` |
12
+ | `gpu_ids` / `gpus` payload fields | `npu_ids` / `npus` |
13
+ | `~/.keepgpu` | `~/.keepnpu` |
14
+ | CUDA, ROCm, or MPS backend | Ascend `torch_npu` backend |
15
+
16
+ The blocking CLI, background service commands, job lifecycle, REST resources,
17
+ JSON-RPC methods, MCP tools, validation limits, dashboard flow, exit handling,
18
+ and utilization-backoff policy otherwise retain the KeepGPU behavior.
19
+
20
+ Intentional backend differences:
21
+
22
+ - `torch_npu` is imported lazily so help, validation, and service health remain
23
+ usable on a machine without the Ascend runtime.
24
+ - Device selectors are torch-visible ordinals. This avoids confusing a physical
25
+ card/chip ID with the post-filter ordinal accepted by `torch.npu.set_device`.
26
+ - `npu-smi` formats differ across Ascend products and driver versions. KeepNPU
27
+ treats telemetry as best effort and returns nullable metrics when a value
28
+ cannot be established safely.
29
+ - KeepNPU allocates float32 chunks and performs small in-place ReLU operations;
30
+ it does not assume CUDA-specific allocator or stream APIs. Ascend defaults to
31
+ one pass over the allocation per interval because KeepGPU's 5,000-pass GPU
32
+ default would generate roughly 10 TiB of memory traffic for a 1 GiB target.
33
+ - Hardware/vendor setup is not declared as a PyPI dependency because PyTorch,
34
+ `torch_npu`, CANN, and the driver must be installed as a compatible set.
@@ -0,0 +1,31 @@
1
+ # Releasing KeepNPU
2
+
3
+ KeepNPU publishes the normalized distribution name `keep-npu`. A release
4
+ provides these commands after `python -m pip install keep-npu`:
5
+
6
+ - `keep-npu`
7
+ - `keep-npu-mcp-server`
8
+ - `keep-npu-alive`
9
+
10
+ ## One-time PyPI setup
11
+
12
+ Configure a pending trusted publisher for the `keep-npu` project with:
13
+
14
+ - PyPI project name: `keep-npu`
15
+ - GitHub owner: `pzheng460`
16
+ - GitHub repository: `keep-npu`
17
+ - Workflow filename: `publish-pypi.yml`
18
+ - Environment name: `pypi`
19
+
20
+ No long-lived PyPI token is stored in GitHub. PyPI verifies the GitHub Actions
21
+ OIDC identity when the publish job runs.
22
+
23
+ ## Publish a version
24
+
25
+ 1. Update `__version__` and the matching `tool.bumpversion.current_version`.
26
+ 2. Run the Python, dashboard, build, and installed-wheel checks.
27
+ 3. Push the release commit and create a GitHub release tagged `vX.Y.Z`.
28
+ 4. The release event builds a fresh sdist and wheel, then publishes both through
29
+ PyPI trusted publishing.
30
+
31
+ The workflow can also be started manually after the same tag/version checks.
@@ -0,0 +1,162 @@
1
+ # KeepGPU-Compatible KeepNPU Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Build an Ascend-native `keep-npu` package whose renamed public interfaces and lifecycle behavior match KeepGPU 1.0.0/current compatibility fixes, then validate it on configured SSH NPU hosts.
6
+
7
+ **Architecture:** Port the tested KeepGPU package, service, dashboard, and test boundaries with a deterministic GPU-to-NPU naming map. Replace the platform-specific controllers and telemetry with one dependency-injected Ascend backend using `torch_npu` and `npu-smi`, while retaining the upstream validation, protocol, concurrency, and daemon-safety contracts.
8
+
9
+ **Tech Stack:** Python 3.9–3.13, setuptools, Typer, Rich, PyTorch + torch_npu, stdlib HTTP/JSON-RPC, React/Vite/Vitest/Tailwind, pytest.
10
+
11
+ ## Global Constraints
12
+
13
+ - Reference behavior is KeepGPU upstream commit `691720383f5325cffb9fc5960304541caec31444` and release 1.0.0.
14
+ - Public names use `keep-npu`, `keep-npu-mcp-server`, `--npu-ids`, `list-npus`, `npu_ids`, `npus`, and `~/.keepnpu`.
15
+ - Default service endpoint is `127.0.0.1:8765`.
16
+ - Unknown utilization is `null` and causes backoff unless `busy_threshold=-1`.
17
+ - Remote work uses unique temporary directories and leaves no daemon or workload behind.
18
+ - Production behavior is introduced only after a corresponding test has been observed failing.
19
+
20
+ ---
21
+
22
+ ### Task 1: Port the public contract and package skeleton
23
+
24
+ **Files:**
25
+ - Create: `pyproject.toml`
26
+ - Create: `src/keep_npu/__init__.py`
27
+ - Create: `src/keep_npu/utilities/*.py`
28
+ - Create: `tests/utilities/*.py`
29
+ - Create: `tests/test_package_metadata.py`
30
+ - Modify: `.gitignore`
31
+
32
+ **Interfaces:**
33
+ - Produces: validators `validate_interval`, `validate_busy_threshold`, `validate_npu_ids`, `validate_job_id`; `parse_size`; strict JSON helpers; endpoint validators.
34
+ - Consumes: no project interfaces.
35
+
36
+ - [ ] Copy the upstream metadata and utility tests, mechanically map the approved public names, and run `pytest tests/utilities tests/test_package_metadata.py -q`; expect collection/import failure because `keep_npu` does not exist.
37
+ - [ ] Add the mapped package metadata and utility modules, keeping numeric, size, endpoint, session-id, and strict-JSON limits unchanged.
38
+ - [ ] Run `pytest tests/utilities tests/test_package_metadata.py -q`; expect all selected tests to pass.
39
+ - [ ] Run `python -m build`; expect wheel and source distribution creation with both console entry points declared.
40
+ - [ ] Commit with `feat: add KeepNPU package contracts`.
41
+
42
+ ### Task 2: Implement Ascend discovery, telemetry, and controllers
43
+
44
+ **Files:**
45
+ - Create: `src/keep_npu/utilities/platform_manager.py`
46
+ - Create: `src/keep_npu/utilities/npu_info.py`
47
+ - Create: `src/keep_npu/utilities/npu_monitor.py`
48
+ - Create: `src/keep_npu/single_npu_controller/base_npu_controller.py`
49
+ - Create: `src/keep_npu/single_npu_controller/ascend_npu_controller.py`
50
+ - Create: `src/keep_npu/global_npu_controller/global_npu_controller.py`
51
+ - Create: `tests/npu_controller/*.py`
52
+ - Create: `tests/global_controller/*.py`
53
+ - Create: `tests/fixtures/npu_smi/*.txt`
54
+
55
+ **Interfaces:**
56
+ - Consumes: Task 1 validators and size parsing.
57
+ - Produces: `visible_torch_device_count()`, `list_npus()`, `NPUInfo`, `AscendNPUController`, and `GlobalNPUController`.
58
+
59
+ - [ ] Port controller contract, timing, rollback, release, and health tests with fake Torch/NPU adapters; run them and expect import failure for controller modules.
60
+ - [ ] Add `npu-smi` fixture tests for table parsing, missing fields, invalid utilization, inconsistent memory, and command failure; run and expect missing parser failures.
61
+ - [ ] Implement lazy `torch`/`torch_npu` discovery and visible ordinal selection without importing hardware libraries during local validation.
62
+ - [ ] Implement telemetry parsing that returns nullable fields and never converts unavailable utilization to zero.
63
+ - [ ] Implement chunked float32 allocation, low-cost keepalive work, monotonic interval timing, utilization backoff, runtime health, idempotent keep/release, multi-device rollback, and parallel release.
64
+ - [ ] Run `pytest tests/npu_controller tests/global_controller tests/utilities/test_npu_info.py tests/utilities/test_npu_monitor.py -q`; expect all selected tests to pass.
65
+ - [ ] Commit with `feat: add Ascend NPU controllers and telemetry`.
66
+
67
+ ### Task 3: Port blocking CLI and legacy wrapper
68
+
69
+ **Files:**
70
+ - Create: `src/keep_npu/cli.py`
71
+ - Create: `tests/test_cli_thresholds.py`
72
+ - Create: `tests/test_cli_blocking.py`
73
+ - Modify: `keep_npu_alive.py`
74
+ - Modify: `README.md`
75
+
76
+ **Interfaces:**
77
+ - Consumes: `GlobalNPUController`, Task 1 validators.
78
+ - Produces: `keep-npu` blocking mode and compatibility wrapper behavior.
79
+
80
+ - [ ] Port the upstream blocking CLI tests with `--npu-ids`; add regression cases for `nan`, `inf`, duplicate IDs, signed zero, full-width digits, and root options before subcommands; run and expect CLI import/behavior failures.
81
+ - [ ] Implement the Typer root command with defaults `interval=300`, `vram=1GiB`, `busy_threshold=25`, all-visible NPUs, legacy `--threshold`, and plain validation errors.
82
+ - [ ] Convert `keep_npu_alive.py` into a wrapper that translates `--device`, `--interval`, and the legacy matrix-size flags into the new controller path while retaining `--once` as a bounded compatibility smoke operation.
83
+ - [ ] Run `pytest tests/test_cli_thresholds.py tests/test_cli_blocking.py tests/test_keep_npu_alive.py -q`; expect all selected tests to pass.
84
+ - [ ] Run `PYTHONPATH=src python -m keep_npu.cli --help`; expect mapped NPU options and all service subcommands.
85
+ - [ ] Commit with `feat: add KeepNPU blocking CLI`.
86
+
87
+ ### Task 4: Port service lifecycle and service CLI
88
+
89
+ **Files:**
90
+ - Create: `src/keep_npu/mcp/server.py`
91
+ - Create: `tests/mcp/test_server.py`
92
+ - Create: `tests/test_cli_service_commands.py`
93
+
94
+ **Interfaces:**
95
+ - Consumes: `GlobalNPUController`, `list_npus()`, all shared validators.
96
+ - Produces: `KeepNPUServer.start_keep`, `stop_keep`, `status`, `list_npus`; CLI `serve/start/status/stop/list-npus/service-stop`.
97
+
98
+ - [ ] Port the upstream session concurrency, starting/stopping, runtime failure, release timeout, and status contract tests with the naming map; run and expect missing server failures.
99
+ - [ ] Port service CLI tests for local validation, auto-start rollback, machine JSON purity, malformed RPC envelopes, ownership records, and safe daemon stop; run and expect missing commands.
100
+ - [ ] Implement the shared session registry and lifecycle states without holding the registry lock during slow controller startup or health probes.
101
+ - [ ] Implement CLI RPC clients, result validators, daemon auto-start, endpoint-specific logs/PID records, ownership verification, stop-all fallback, and command hints.
102
+ - [ ] Run `pytest tests/mcp/test_server.py tests/test_cli_service_commands.py -q`; expect all selected tests to pass.
103
+ - [ ] Commit with `feat: add KeepNPU service workflows`.
104
+
105
+ ### Task 5: Port REST, JSON-RPC, MCP, and dashboard
106
+
107
+ **Files:**
108
+ - Create: `tests/mcp/test_http_api.py`
109
+ - Create: `web/dashboard/**`
110
+ - Create: `src/keep_npu/mcp/static/index.html`
111
+ - Create: `src/keep_npu/mcp/static/assets/*`
112
+
113
+ **Interfaces:**
114
+ - Consumes: `KeepNPUServer` direct methods.
115
+ - Produces: REST `/api/npus` and session endpoints, JSON-RPC `/` and `/rpc`, stdio MCP lifecycle/tools, and the KeepNPU dashboard.
116
+
117
+ - [ ] Port HTTP routing, strict request-body, JSON-RPC envelope, MCP lifecycle, method/error classification, HEAD/static asset, and dashboard API tests; run and expect route/asset failures.
118
+ - [ ] Implement HTTP and stdio transports with exact NPU-native result keys and upstream route-hardening behavior.
119
+ - [ ] Port dashboard source and tests with NPU labels and `/api/npus`; run `npm test -- --run` in `web/dashboard` and expect failures before mapped components are complete.
120
+ - [ ] Complete the mapped React dashboard, run `npm run build`, and synchronize built assets into `src/keep_npu/mcp/static`.
121
+ - [ ] Run `pytest tests/mcp -q` and `npm test -- --run`; expect all selected tests to pass.
122
+ - [ ] Commit with `feat: add KeepNPU APIs and dashboard`.
123
+
124
+ ### Task 6: Full compatibility and packaging verification
125
+
126
+ **Files:**
127
+ - Create/modify: mapped remaining tests under `tests/`
128
+ - Create: `docs/compatibility.md`
129
+ - Modify: `README.md`
130
+ - Modify: `MANIFEST.in`
131
+
132
+ **Interfaces:**
133
+ - Consumes: all prior public interfaces.
134
+ - Produces: reproducible compatibility evidence and installable artifacts.
135
+
136
+ - [ ] Port every remaining hardware-independent upstream test and run the full suite; record and fix each mapped contract failure using a failing regression test first.
137
+ - [ ] Run `python -m pytest -q`, `ruff check .`, and `python -m compileall -q src tests keep_npu_alive.py`; expect clean output.
138
+ - [ ] Build wheel/sdist, install the wheel into a temporary virtual environment, and smoke-test `keep-npu --help` plus `keep-npu-mcp-server --help`.
139
+ - [ ] Build dashboard production assets and verify packaged assets match the React build.
140
+ - [ ] Document the explicit name mapping, supported Python/CANN expectations, CLI/API examples, and known platform-only differences.
141
+ - [ ] Commit with `test: complete KeepGPU compatibility coverage`.
142
+
143
+ ### Task 7: SSH Ascend validation and hardware corrections
144
+
145
+ **Files:**
146
+ - Create: `docs/validation/ascend-remote-results.md`
147
+ - Create/modify: telemetry fixtures and regression tests discovered from hardware.
148
+ - Modify: hardware modules only when a failing remote case is reproduced locally.
149
+
150
+ **Interfaces:**
151
+ - Consumes: built KeepNPU artifact and configured SSH hosts.
152
+ - Produces: remote evidence, platform corrections, and cleanup verification.
153
+
154
+ - [ ] Discover SSH host aliases read-only and preflight each reachable candidate with bounded commands for `npu-smi`, Python, CANN variables, `torch`, `torch_npu`, and device count.
155
+ - [ ] Select at least two usable environments, or multiple devices on one host, based on availability and current memory pressure.
156
+ - [ ] Rsync only source, tests, metadata, docs, and built dashboard assets to a unique `/tmp/keep-npu-<timestamp>` directory on each target.
157
+ - [ ] Run remote unit smoke tests, `list-npus`, a low-memory short blocking session, and before/during/after telemetry; use explicit timeouts and capture logs.
158
+ - [ ] Run service lifecycle, REST, JSON-RPC, MCP, dashboard endpoint, multi-NPU, invalid-selection, signal, repeated-stop, and rollback checks.
159
+ - [ ] For each hardware discrepancy, add a local failing fixture/regression test, implement the smallest correction, rerun locally, redeploy, and rerun the affected remote check.
160
+ - [ ] Stop all test sessions and services, verify no KeepNPU process remains, verify memory recovery, and remove each remote temporary directory.
161
+ - [ ] Write exact host/runtime/device/version/result evidence and any irreducible Ascend differences to `docs/validation/ascend-remote-results.md`.
162
+ - [ ] Run the complete local verification suite once more and commit with `test: validate KeepNPU on Ascend hardware`.