noqt commited on
Commit
2c2b859
·
verified ·
1 Parent(s): db81a9b

Sync GitHub source 8ab9513367be0d2c0dcee1f38cfd7178aa71c7dd

Browse files

Canonical source: https://github.com/noqt/Lumi-Eggcracker/commit/8ab9513367be0d2c0dcee1f38cfd7178aa71c7dd

HUGGINGFACE_MANIFEST.json CHANGED
@@ -37,8 +37,8 @@
37
  "size": 10537
38
  },
39
  "README.md": {
40
- "sha256": "f4a7951d86f828e92d371af6895b2ad7ff7fc9343f95e5830633e37586cc051c",
41
- "size": 31089
42
  },
43
  "RELEASE_NOTES.md": {
44
  "sha256": "64d330d0f297b15720fc65e6347ececc1b99a917a597d405ebfac04baf3222ea",
@@ -189,7 +189,7 @@
189
  "size": 4101
190
  },
191
  "index.html": {
192
- "sha256": "60aec61bda5ecd0df3bf9498d80af1ed50d34beca7670d3183b64affb43cd0e9",
193
  "size": 22790
194
  },
195
  "integrations/prometheus/eggcracker.rules.yml": {
@@ -437,8 +437,8 @@
437
  "size": 55591
438
  },
439
  "src/lumi_eggcracker/cli.py": {
440
- "sha256": "ca7675de60a8a58d303f924f4a0f2f3a89346f29cf02cd3dba52bd8112c722d4",
441
- "size": 10518
442
  },
443
  "src/lumi_eggcracker/client.py": {
444
  "sha256": "0ac5dd4fdf564b2b7fd9e74de66d9ff083ac153864867b69fc078da9d66bbc66",
@@ -589,8 +589,8 @@
589
  "size": 7176
590
  },
591
  "tests/test_cli.py": {
592
- "sha256": "b03872e0b0ebffaeb964eceb85320115b76a6c5ece5b0bce64d79a9a575b7db1",
593
- "size": 12128
594
  },
595
  "tests/test_collect_supported_path_receipt.py": {
596
  "sha256": "79ae57bf3d78cac5fbe1b9d7db60462328f70cb17214bc75a5b5e7eff3ea0eef",
@@ -827,6 +827,6 @@
827
  },
828
  "schema": "noqt.huggingface_manifest.v1",
829
  "source_repository": "https://github.com/noqt/Lumi-Eggcracker",
830
- "source_revision": "a82d86680dc86d442a0f45ca3e8ddec915b125cb",
831
- "source_url": "https://github.com/noqt/Lumi-Eggcracker/commit/a82d86680dc86d442a0f45ca3e8ddec915b125cb"
832
  }
 
37
  "size": 10537
38
  },
39
  "README.md": {
40
+ "sha256": "8d42000b36c3560d5e78054c94b9c547fe19214ad42bd1791837bb286a3370d4",
41
+ "size": 31503
42
  },
43
  "RELEASE_NOTES.md": {
44
  "sha256": "64d330d0f297b15720fc65e6347ececc1b99a917a597d405ebfac04baf3222ea",
 
189
  "size": 4101
190
  },
191
  "index.html": {
192
+ "sha256": "7e4f35f1f1b8e600fc69bf7da573dac5c23a6d74b20d55623fb0b5779e53bb18",
193
  "size": 22790
194
  },
195
  "integrations/prometheus/eggcracker.rules.yml": {
 
437
  "size": 55591
438
  },
439
  "src/lumi_eggcracker/cli.py": {
440
+ "sha256": "3be4ce117402ec750f9d86acdfe050e8dca16696f7450d19de7b51250e80e8ed",
441
+ "size": 15504
442
  },
443
  "src/lumi_eggcracker/client.py": {
444
  "sha256": "0ac5dd4fdf564b2b7fd9e74de66d9ff083ac153864867b69fc078da9d66bbc66",
 
589
  "size": 7176
590
  },
591
  "tests/test_cli.py": {
592
+ "sha256": "727d8d5f855c877320488c4064edbb0dc03e6f68b73ce472eb1803fe58089d2e",
593
+ "size": 18895
594
  },
595
  "tests/test_collect_supported_path_receipt.py": {
596
  "sha256": "79ae57bf3d78cac5fbe1b9d7db60462328f70cb17214bc75a5b5e7eff3ea0eef",
 
827
  },
828
  "schema": "noqt.huggingface_manifest.v1",
829
  "source_repository": "https://github.com/noqt/Lumi-Eggcracker",
830
+ "source_revision": "8ab9513367be0d2c0dcee1f38cfd7178aa71c7dd",
831
+ "source_url": "https://github.com/noqt/Lumi-Eggcracker/commit/8ab9513367be0d2c0dcee1f38cfd7178aa71c7dd"
832
  }
HUGGINGFACE_SYNC.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "manifest": "HUGGINGFACE_MANIFEST.json",
3
- "manifest_sha256": "3999dc00867639421942326d6ddadb8c3cfbf8032024897234e369556ed5b584",
4
  "mirrored_files": 191,
5
  "mode": "DERIVED_READ_ONLY_MIRROR",
6
  "release_reference": {
@@ -65,7 +65,7 @@
65
  },
66
  "schema": "noqt.huggingface_sync.v1",
67
  "source_repository": "https://github.com/noqt/Lumi-Eggcracker",
68
- "source_revision": "a82d86680dc86d442a0f45ca3e8ddec915b125cb",
69
- "source_url": "https://github.com/noqt/Lumi-Eggcracker/commit/a82d86680dc86d442a0f45ca3e8ddec915b125cb",
70
  "target": "https://huggingface.co/spaces/noqt/eggcracker"
71
  }
 
1
  {
2
  "manifest": "HUGGINGFACE_MANIFEST.json",
3
+ "manifest_sha256": "73af8a2e51b02f3016f7aff8ab7a04af7d918d474ef8a7a109389d8f9700af4a",
4
  "mirrored_files": 191,
5
  "mode": "DERIVED_READ_ONLY_MIRROR",
6
  "release_reference": {
 
65
  },
66
  "schema": "noqt.huggingface_sync.v1",
67
  "source_repository": "https://github.com/noqt/Lumi-Eggcracker",
68
+ "source_revision": "8ab9513367be0d2c0dcee1f38cfd7178aa71c7dd",
69
+ "source_url": "https://github.com/noqt/Lumi-Eggcracker/commit/8ab9513367be0d2c0dcee1f38cfd7178aa71c7dd",
70
  "target": "https://huggingface.co/spaces/noqt/eggcracker"
71
  }
README.md CHANGED
@@ -11,7 +11,7 @@ short_description: Native Linux kill switch for supported local-AI workloads
11
  ---
12
 
13
  > Official noqt Hugging Face distribution, generated from GitHub commit
14
- > [`a82d86680dc8`](https://github.com/noqt/Lumi-Eggcracker/commit/a82d86680dc86d442a0f45ca3e8ddec915b125cb). This Space distributes the source for
15
  > discovery and cloning; Eggcracker itself runs on a supported native Linux
16
  > host, not on Hugging Face. A snapshot is called current only after the
17
  > release-linked sync job verifies its returned Hub commit and full manifest.
@@ -547,6 +547,20 @@ exports only; it does not authenticate them or verify a live workload. See
547
  [the export and comparison guide](docs/DETECTION_RECEIPT_EXPORT.md) for input,
548
  output, redaction and filesystem behavior.
549
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
550
  ## Install and remove
551
 
552
  The first-kill command is the recommended campaign path. A release is complete
 
11
  ---
12
 
13
  > Official noqt Hugging Face distribution, generated from GitHub commit
14
+ > [`8ab9513367be`](https://github.com/noqt/Lumi-Eggcracker/commit/8ab9513367be0d2c0dcee1f38cfd7178aa71c7dd). This Space distributes the source for
15
  > discovery and cloning; Eggcracker itself runs on a supported native Linux
16
  > host, not on Hugging Face. A snapshot is called current only after the
17
  > release-linked sync job verifies its returned Hub commit and full manifest.
 
547
  [the export and comparison guide](docs/DETECTION_RECEIPT_EXPORT.md) for input,
548
  output, redaction and filesystem behavior.
549
 
550
+ ## Check installed health
551
+
552
+ For an installed source/build containing this change, record its version and
553
+ then request the bounded health snapshot:
554
+
555
+ ```sh
556
+ eggcracker version
557
+ eggcracker doctor --summary
558
+ ```
559
+
560
+ The snapshot is not containment proof. `doctor --summary` is available only in
561
+ the source/build that contains this change; its presence is not a claim that
562
+ the published v1.0.10 release includes this option.
563
+
564
  ## Install and remove
565
 
566
  The first-kill command is the recommended campaign path. A release is complete
index.html CHANGED
@@ -4,7 +4,7 @@
4
  <meta charset="utf-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
  <meta name="description" content="Lumi Eggcracker is noqt's native Linux kill switch for unapproved supported local-AI workloads. Clone the complete source from Hugging Face.">
7
- <meta name="noqt-source-revision" content="a82d86680dc86d442a0f45ca3e8ddec915b125cb">
8
  <meta name="theme-color" content="#090a0c">
9
  <title>Lumi Eggcracker — Native Linux AI kill switch</title>
10
  <style>
@@ -649,7 +649,7 @@ sudo /usr/bin/python3 -I -S scripts/first_kill.py \
649
  <section>
650
  <div class="shell source-bar">
651
  <div>
652
- <div class="source-id">SOURCE COMMIT · a82d86680dc8</div>
653
  <h2>Inspect every line.</h2>
654
  <p>Complete source, tests, qualification documents and reproducible proof tooling are distributed in this repository.</p>
655
  </div>
 
4
  <meta charset="utf-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
  <meta name="description" content="Lumi Eggcracker is noqt's native Linux kill switch for unapproved supported local-AI workloads. Clone the complete source from Hugging Face.">
7
+ <meta name="noqt-source-revision" content="8ab9513367be0d2c0dcee1f38cfd7178aa71c7dd">
8
  <meta name="theme-color" content="#090a0c">
9
  <title>Lumi Eggcracker — Native Linux AI kill switch</title>
10
  <style>
 
649
  <section>
650
  <div class="shell source-bar">
651
  <div>
652
+ <div class="source-id">SOURCE COMMIT · 8ab9513367be</div>
653
  <h2>Inspect every line.</h2>
654
  <p>Complete source, tests, qualification documents and reproducible proof tooling are distributed in this repository.</p>
655
  </div>
src/lumi_eggcracker/cli.py CHANGED
@@ -18,6 +18,122 @@ from .support_bundle import main as support_bundle_main
18
  from .support_bundle import validate_main as validate_support_bundle_main
19
  from .watchdog import main as watchdog_main
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  class _RejectDuplicateIdentifier(argparse.Action):
23
  """Accept one identifier option and fail closed on a repeated spelling."""
@@ -102,7 +218,12 @@ def _parser() -> argparse.ArgumentParser:
102
  ):
103
  command = incident_commands.add_parser(action, help=help_text)
104
  command.add_argument("incident_id")
105
- commands.add_parser("doctor", help="check the installed protected supervisor")
 
 
 
 
 
106
  support = commands.add_parser(
107
  "support-bundle", help="write a local redacted health and receipt bundle"
108
  )
@@ -149,6 +270,14 @@ def main(argv: list[str] | None = None) -> int:
149
  return support_bundle_main(args.output)
150
  try:
151
  if args.command == "doctor":
 
 
 
 
 
 
 
 
152
  value = request("doctor")
153
  print(json.dumps(value, sort_keys=True))
154
  return 0 if value.get("result") == "PASS" else 6
 
18
  from .support_bundle import validate_main as validate_support_bundle_main
19
  from .watchdog import main as watchdog_main
20
 
21
+ _DOCTOR_SUMMARY_SCHEMA = "lumi-eggcracker.doctor-summary.v1"
22
+ _DOCTOR_SUMMARY_ERROR = "eggcracker: doctor summary unavailable"
23
+ _DOCTOR_SUMMARY_INSTALLATION_STATES = frozenset(
24
+ {"HEALTHY", "DRIFT", "RECOVERY_REQUIRED", "NOT_INSTALLED"}
25
+ )
26
+ _DOCTOR_SUMMARY_NETWORK_MODES = frozenset({"offline", "unsupported"})
27
+
28
+
29
+ class _DoctorSummaryInvalid(ValueError):
30
+ """The supervisor response cannot be safely reduced to a doctor summary."""
31
+
32
+
33
+ def _doctor_summary(value: object) -> dict[str, object]:
34
+ """Reduce a doctor response to a fixed, nonidentifying health object."""
35
+
36
+ if type(value) is not dict:
37
+ raise _DoctorSummaryInvalid
38
+
39
+ result = value.get("result")
40
+ if type(result) is not str or result not in {"PASS", "UNSUPPORTED"}:
41
+ raise _DoctorSummaryInvalid
42
+
43
+ def required_bool(container: object, key: str) -> bool:
44
+ if type(container) is not dict or key not in container:
45
+ raise _DoctorSummaryInvalid
46
+ item = container[key]
47
+ if type(item) is not bool:
48
+ raise _DoctorSummaryInvalid
49
+ return item
50
+
51
+ autonomous_discovery = required_bool(value, "autonomous_discovery")
52
+ cgroup_v2 = required_bool(value, "cgroup_v2")
53
+ pidfd = required_bool(value, "pidfd")
54
+
55
+ network = value.get("network")
56
+ if type(network) is not dict:
57
+ raise _DoctorSummaryInvalid
58
+ network_mode = network.get("mode")
59
+ if type(network_mode) is not str or network_mode not in _DOCTOR_SUMMARY_NETWORK_MODES:
60
+ raise _DoctorSummaryInvalid
61
+ network_primitives = network.get("primitives")
62
+ primitives_supported = required_bool(network_primitives, "supported")
63
+ network_cleanup = required_bool(network, "cleanup_healthy")
64
+
65
+ execution_boundary = value.get("execution_boundary")
66
+ execution_supported = required_bool(execution_boundary, "supported")
67
+
68
+ discovery = value.get("discovery")
69
+ discovery_healthy = required_bool(discovery, "healthy")
70
+ receipt_persistence = required_bool(discovery, "receipt_persistence_healthy")
71
+
72
+ incidents = value.get("incidents")
73
+ incidents_healthy = required_bool(incidents, "healthy")
74
+ incidents_lockdown = required_bool(incidents, "lockdown")
75
+ if not incidents_healthy and not incidents_lockdown:
76
+ raise _DoctorSummaryInvalid
77
+
78
+ installation = value.get("installation")
79
+ if type(installation) is not dict or "state" not in installation:
80
+ raise _DoctorSummaryInvalid
81
+ installation_state = installation["state"]
82
+ if (
83
+ type(installation_state) is not str
84
+ or installation_state not in _DOCTOR_SUMMARY_INSTALLATION_STATES
85
+ ):
86
+ raise _DoctorSummaryInvalid
87
+
88
+ workload_identity = value.get("workload_identity")
89
+ workload_identity_healthy = required_bool(workload_identity, "healthy")
90
+
91
+ failed_checks: set[str] = set()
92
+ if not cgroup_v2:
93
+ failed_checks.add("cgroup_v2")
94
+ if not pidfd:
95
+ failed_checks.add("pidfd")
96
+ if network_mode != "offline":
97
+ failed_checks.add("network_mode")
98
+ if not primitives_supported:
99
+ failed_checks.add("network_primitives")
100
+ if not network_cleanup:
101
+ failed_checks.add("network_cleanup")
102
+ if not execution_supported:
103
+ failed_checks.add("execution_boundary")
104
+ if not discovery_healthy:
105
+ failed_checks.add("discovery")
106
+ if not receipt_persistence:
107
+ failed_checks.add("receipt_persistence")
108
+ if not incidents_healthy:
109
+ failed_checks.add("incidents")
110
+ if installation_state != "HEALTHY":
111
+ failed_checks.add("installation")
112
+ if not workload_identity_healthy:
113
+ failed_checks.add("workload_identity")
114
+
115
+ if result == "PASS":
116
+ if not autonomous_discovery or failed_checks:
117
+ raise _DoctorSummaryInvalid
118
+ summary_result = "READY"
119
+ else:
120
+ if autonomous_discovery:
121
+ raise _DoctorSummaryInvalid
122
+ if not failed_checks:
123
+ # The supervisor also gates readiness on quarantine_root, which is
124
+ # deliberately not exposed by its public doctor response.
125
+ failed_checks.add("supervisor_readiness")
126
+ summary_result = "NOT_READY"
127
+
128
+ return {
129
+ "failed_checks": sorted(failed_checks),
130
+ "next_action": (
131
+ "NONE" if summary_result == "READY" else "REVIEW_SUPERVISOR_READINESS"
132
+ ),
133
+ "result": summary_result,
134
+ "schema": _DOCTOR_SUMMARY_SCHEMA,
135
+ }
136
+
137
 
138
  class _RejectDuplicateIdentifier(argparse.Action):
139
  """Accept one identifier option and fail closed on a repeated spelling."""
 
218
  ):
219
  command = incident_commands.add_parser(action, help=help_text)
220
  command.add_argument("incident_id")
221
+ doctor = commands.add_parser("doctor", help="check the installed protected supervisor")
222
+ doctor.add_argument(
223
+ "--summary",
224
+ action="store_true",
225
+ help="emit a bounded readiness summary instead of the full doctor response",
226
+ )
227
  support = commands.add_parser(
228
  "support-bundle", help="write a local redacted health and receipt bundle"
229
  )
 
270
  return support_bundle_main(args.output)
271
  try:
272
  if args.command == "doctor":
273
+ if args.summary:
274
+ try:
275
+ summary = _doctor_summary(request("doctor"))
276
+ except Exception: # noqa: BLE001 - summary failures are intentionally constant
277
+ print(_DOCTOR_SUMMARY_ERROR, file=sys.stderr)
278
+ return 6
279
+ print(json.dumps(summary, sort_keys=True))
280
+ return 0 if summary["result"] == "READY" else 6
281
  value = request("doctor")
282
  print(json.dumps(value, sort_keys=True))
283
  return 0 if value.get("result") == "PASS" else 6
tests/test_cli.py CHANGED
@@ -11,6 +11,35 @@ from unittest.mock import patch
11
  from lumi_eggcracker.cli import main
12
 
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  class CliTests(unittest.TestCase):
15
  def test_version(self) -> None:
16
  output = io.StringIO()
@@ -41,6 +70,128 @@ class CliTests(unittest.TestCase):
41
  self.assertNotIn("_supervisor", help_text)
42
  self.assertNotIn("network" + "-deny", help_text)
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  def test_compare_detection_receipts_help_uses_installed_command(self) -> None:
45
  output = io.StringIO()
46
  with redirect_stdout(output), self.assertRaises(SystemExit) as raised:
 
11
  from lumi_eggcracker.cli import main
12
 
13
 
14
+ def doctor_response(**overrides: object) -> dict[str, object]:
15
+ value: dict[str, object] = {
16
+ "autonomous_discovery": True,
17
+ "backend": "root-supervisor",
18
+ "cgroup_v2": True,
19
+ "catalogue": {"secret": "catalogue-canary"},
20
+ "discovery": {
21
+ "healthy": True,
22
+ "receipt_persistence_healthy": True,
23
+ "path": "/private/discovery-canary",
24
+ },
25
+ "execution_boundary": {"supported": True, "argv": ["argv-canary"]},
26
+ "incidents": {"healthy": True, "lockdown": False, "secret": "incident-canary"},
27
+ "installation": {"state": "HEALTHY", "path": "/private/install-canary"},
28
+ "network": {
29
+ "cleanup_healthy": True,
30
+ "mode": "offline",
31
+ "primitives": {"supported": True, "uid": "uid-canary"},
32
+ },
33
+ "pidfd": True,
34
+ "result": "PASS",
35
+ "version": "1.0.10",
36
+ "workload_identity": {"healthy": True, "uid": 4242},
37
+ "workload_uid": 4242,
38
+ }
39
+ value.update(overrides)
40
+ return value
41
+
42
+
43
  class CliTests(unittest.TestCase):
44
  def test_version(self) -> None:
45
  output = io.StringIO()
 
70
  self.assertNotIn("_supervisor", help_text)
71
  self.assertNotIn("network" + "-deny", help_text)
72
 
73
+ def test_doctor_summary_ready_is_fixed_and_nonidentifying(self) -> None:
74
+ response = doctor_response()
75
+ output = io.StringIO()
76
+ error = io.StringIO()
77
+ with patch("lumi_eggcracker.cli.request", return_value=response) as request, redirect_stdout(output), redirect_stderr(error):
78
+ self.assertEqual(0, main(["doctor", "--summary"]))
79
+ self.assertEqual(
80
+ {
81
+ "failed_checks": [],
82
+ "next_action": "NONE",
83
+ "result": "READY",
84
+ "schema": "lumi-eggcracker.doctor-summary.v1",
85
+ },
86
+ json.loads(output.getvalue()),
87
+ )
88
+ self.assertEqual("", error.getvalue())
89
+ self.assertNotIn("canary", output.getvalue())
90
+ request.assert_called_once_with("doctor")
91
+
92
+ def test_doctor_summary_mixed_failures_are_sorted_and_deduplicated(self) -> None:
93
+ response = doctor_response(
94
+ autonomous_discovery=False,
95
+ cgroup_v2=False,
96
+ execution_boundary={"supported": False},
97
+ discovery={"healthy": False, "receipt_persistence_healthy": False},
98
+ incidents={"healthy": False, "lockdown": True},
99
+ installation={"state": "DRIFT"},
100
+ network={
101
+ "cleanup_healthy": False,
102
+ "mode": "unsupported",
103
+ "primitives": {"supported": False},
104
+ },
105
+ pidfd=False,
106
+ result="UNSUPPORTED",
107
+ workload_identity={"healthy": False},
108
+ )
109
+ output = io.StringIO()
110
+ with patch("lumi_eggcracker.cli.request", return_value=response), redirect_stdout(output):
111
+ self.assertEqual(6, main(["doctor", "--summary"]))
112
+ summary = json.loads(output.getvalue())
113
+ self.assertEqual(
114
+ [
115
+ "cgroup_v2",
116
+ "discovery",
117
+ "execution_boundary",
118
+ "incidents",
119
+ "installation",
120
+ "network_cleanup",
121
+ "network_mode",
122
+ "network_primitives",
123
+ "pidfd",
124
+ "receipt_persistence",
125
+ "workload_identity",
126
+ ],
127
+ summary["failed_checks"],
128
+ )
129
+ self.assertEqual(len(summary["failed_checks"]), len(set(summary["failed_checks"])))
130
+ self.assertEqual("NOT_READY", summary["result"])
131
+ self.assertEqual("REVIEW_SUPERVISOR_READINESS", summary["next_action"])
132
+ self.assertEqual(
133
+ {"failed_checks", "next_action", "result", "schema"},
134
+ set(summary),
135
+ )
136
+ self.assertNotIn("canary", output.getvalue())
137
+
138
+ def test_doctor_summary_unsupported_without_visible_failure_is_honest(self) -> None:
139
+ response = doctor_response(autonomous_discovery=False, result="UNSUPPORTED")
140
+ output = io.StringIO()
141
+ with patch("lumi_eggcracker.cli.request", return_value=response), redirect_stdout(output):
142
+ self.assertEqual(6, main(["doctor", "--summary"]))
143
+ self.assertEqual(
144
+ {
145
+ "failed_checks": ["supervisor_readiness"],
146
+ "next_action": "REVIEW_SUPERVISOR_READINESS",
147
+ "result": "NOT_READY",
148
+ "schema": "lumi-eggcracker.doctor-summary.v1",
149
+ },
150
+ json.loads(output.getvalue()),
151
+ )
152
+
153
+ def test_doctor_summary_malformed_or_contradictory_response_is_constant_error(self) -> None:
154
+ malformed = [
155
+ {},
156
+ doctor_response(result=True),
157
+ doctor_response(cgroup_v2="true"),
158
+ doctor_response(network={"mode": "secret-path-canary"}),
159
+ doctor_response(autonomous_discovery=False),
160
+ doctor_response(autonomous_discovery=True, result="UNSUPPORTED"),
161
+ doctor_response(incidents={"healthy": False, "lockdown": False}),
162
+ doctor_response(installation={"state": "PRIVATE-CANARY"}),
163
+ ]
164
+ for response in malformed:
165
+ with self.subTest(response=response):
166
+ output = io.StringIO()
167
+ error = io.StringIO()
168
+ with patch("lumi_eggcracker.cli.request", return_value=response), redirect_stdout(output), redirect_stderr(error):
169
+ self.assertEqual(6, main(["doctor", "--summary"]))
170
+ self.assertEqual("", output.getvalue())
171
+ self.assertEqual("eggcracker: doctor summary unavailable\n", error.getvalue())
172
+ self.assertNotIn("canary", error.getvalue())
173
+
174
+ output = io.StringIO()
175
+ error = io.StringIO()
176
+ with patch("lumi_eggcracker.cli.request", side_effect=OSError("/private/CANARY")), redirect_stdout(output), redirect_stderr(error):
177
+ self.assertEqual(6, main(["doctor", "--summary"]))
178
+ self.assertEqual("", output.getvalue())
179
+ self.assertEqual("eggcracker: doctor summary unavailable\n", error.getvalue())
180
+ self.assertNotIn("CANARY", error.getvalue())
181
+
182
+ def test_default_doctor_output_and_exit_remain_unchanged(self) -> None:
183
+ for result, expected_exit in (("PASS", 0), ("UNSUPPORTED", 6)):
184
+ with self.subTest(result=result):
185
+ response = doctor_response(
186
+ autonomous_discovery=result == "PASS", result=result
187
+ )
188
+ output = io.StringIO()
189
+ error = io.StringIO()
190
+ with patch("lumi_eggcracker.cli.request", return_value=response), redirect_stdout(output), redirect_stderr(error):
191
+ self.assertEqual(expected_exit, main(["doctor"]))
192
+ self.assertEqual(json.dumps(response, sort_keys=True) + "\n", output.getvalue())
193
+ self.assertEqual("", error.getvalue())
194
+
195
  def test_compare_detection_receipts_help_uses_installed_command(self) -> None:
196
  output = io.StringIO()
197
  with redirect_stdout(output), self.assertRaises(SystemExit) as raised: