feat(1.2): decnet fleet — prefork master for the heavy worker tier

Wires the prefork primitive into a CLI command. 'decnet fleet heavy' imports
the shared base floor once in the master, then forks profiler + ttp as
CoW-sharing child processes (own process/GIL, full isolation, shared ~71MB
floor). DB-only tier => systemd unit carries no extra privilege (prefork's
privilege-union cost is nil for this fleet). Unit Conflicts= the profiler/ttp
units it replaces. Heavy per-worker state (ATT&CK/ML) still loads per-child;
warming it in the master to share is deferred until a live RSS measurement
shows the big object graph CoW-shares rather than refcount-dirties.
This commit is contained in:
2026-06-18 19:32:27 -04:00
parent 1a765854ec
commit fcc9a9aad1
4 changed files with 179 additions and 1 deletions

35
tests/cli/test_fleet.py Normal file
View File

@@ -0,0 +1,35 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""CLI surface for ``decnet fleet`` (DECNET 1.2 prefork). The fork/restart
mechanism itself is covered by tests/test_prefork.py."""
from __future__ import annotations
from typer.testing import CliRunner
from decnet.cli import app
from decnet.cli.fleet import _FLEETS, _build_fleet
runner = CliRunner()
def test_fleet_is_registered():
result = runner.invoke(app, ["fleet", "--help"])
assert result.exit_code == 0
assert "fleet" in result.stdout.lower()
def test_unknown_fleet_exits_2():
result = runner.invoke(app, ["fleet", "not-a-fleet"])
assert result.exit_code == 2
assert "unknown fleet" in result.stdout
def test_heavy_fleet_builds_expected_workers():
# _build_fleet imports worker modules + builds thunks but runs nothing
# (no fork, no repo.initialize) — safe to call in-process.
specs = _build_fleet("heavy")
assert set(specs) == {"profiler", "ttp"}
assert all(callable(t) for t in specs.values())
def test_heavy_is_known():
assert "heavy" in _FLEETS