zu-cli 0.1.0__py3-none-any.whl
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.
- zu_cli/__init__.py +0 -0
- zu_cli/build.py +111 -0
- zu_cli/config.py +738 -0
- zu_cli/construct.py +318 -0
- zu_cli/construct_sandbox.py +139 -0
- zu_cli/contribute.py +104 -0
- zu_cli/demo.py +373 -0
- zu_cli/deploy.py +207 -0
- zu_cli/explore.py +93 -0
- zu_cli/guardrails.py +102 -0
- zu_cli/harden.py +221 -0
- zu_cli/main.py +1126 -0
- zu_cli/mcp_server.py +444 -0
- zu_cli/observe.py +69 -0
- zu_cli/offline.py +335 -0
- zu_cli/sandbox.py +276 -0
- zu_cli/scaffold.py +116 -0
- zu_cli/server.py +363 -0
- zu_cli/trace.py +111 -0
- zu_cli-0.1.0.dist-info/METADATA +26 -0
- zu_cli-0.1.0.dist-info/RECORD +23 -0
- zu_cli-0.1.0.dist-info/WHEEL +4 -0
- zu_cli-0.1.0.dist-info/entry_points.txt +4 -0
zu_cli/__init__.py
ADDED
|
File without changes
|
zu_cli/build.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""The construction spine — chain the OFFLINE stages of the sequence into one run.
|
|
2
|
+
|
|
3
|
+
``zu build`` composes what the earlier increments shipped: replay the captured bundle
|
|
4
|
+
offline (stage 3), project the resilient track from that clean run (stage 4), and score
|
|
5
|
+
it against perturbed fixtures (stage 5) — gating the track on the resilience score. The
|
|
6
|
+
output is a production-ready, hardened ``track.json`` next to the agent, produced at $0:
|
|
7
|
+
no model, no network.
|
|
8
|
+
|
|
9
|
+
The two LIVE stages and promotion are deliberately NOT in this spine — they need keys,
|
|
10
|
+
network, or a registry push, and are left behind explicit seams so the cheap, testable
|
|
11
|
+
core stands on its own:
|
|
12
|
+
|
|
13
|
+
* **Stage 2 (capture)** is the one live step; ``zu build`` requires its output
|
|
14
|
+
(``fixtures/capture.json``) and points at ``zu capture`` when it is missing.
|
|
15
|
+
* **Stage 6 (canary)** — one live validation run before promotion — is the live lane,
|
|
16
|
+
guarded by ``_canary`` raising ``NotImplementedError`` so ``--with-canary`` fails
|
|
17
|
+
loudly rather than pretending. It is the next increment.
|
|
18
|
+
* **Stage 7 (promote)** — ``zu pack`` / ``zu deploy`` — is left to its existing commands;
|
|
19
|
+
``zu build`` prints them as the next step.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
from dataclasses import dataclass, field
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
from typing import Any
|
|
27
|
+
|
|
28
|
+
from .harden import HardenReport, harden
|
|
29
|
+
from .offline import Bundle, replay_offline
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class StageResult:
|
|
34
|
+
"""One stage of the spine: its outcome and a one-line detail for the summary."""
|
|
35
|
+
|
|
36
|
+
name: str
|
|
37
|
+
status: str # "ok" | "failed" | "skipped"
|
|
38
|
+
detail: str
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class BuildReport:
|
|
43
|
+
stages: list[StageResult] = field(default_factory=list)
|
|
44
|
+
track_path: str | None = None
|
|
45
|
+
harden: HardenReport | None = None
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def ok(self) -> bool:
|
|
49
|
+
return all(s.status != "failed" for s in self.stages)
|
|
50
|
+
|
|
51
|
+
def _add(self, name: str, status: str, detail: str) -> StageResult:
|
|
52
|
+
s = StageResult(name=name, status=status, detail=detail)
|
|
53
|
+
self.stages.append(s)
|
|
54
|
+
return s
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _canary(spec: Any, cfg: Any) -> None:
|
|
58
|
+
"""Stage 6 — the live canary. The seam for the live lane: one real run guarding
|
|
59
|
+
fixture drift before promotion. Not built here (needs keys + network)."""
|
|
60
|
+
raise NotImplementedError(
|
|
61
|
+
"the live canary (stage 6) is the live lane — it needs keys + network and is the "
|
|
62
|
+
"next increment. Validate manually for now with `zu run <agent>` (live), then "
|
|
63
|
+
"promote with `zu pack` / `zu deploy`."
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
async def build_offline(
|
|
68
|
+
spec: Any, cfg: Any, agent_dir: str | Path, bundle: Bundle, *, min_score: float = 1.0,
|
|
69
|
+
) -> BuildReport:
|
|
70
|
+
"""Run the offline spine — build → record track → harden — and write the hardened
|
|
71
|
+
track. Each stage gates the next: a failed offline build is not tracked, and a track
|
|
72
|
+
that fails the resilience gate is recorded but flagged failed so promotion is held."""
|
|
73
|
+
from zu_core.contracts import Status
|
|
74
|
+
from zu_core.track import record_track
|
|
75
|
+
|
|
76
|
+
report = BuildReport()
|
|
77
|
+
|
|
78
|
+
# Stage 3 — build offline (the keystone). A clean replay is the precondition.
|
|
79
|
+
result, events = await replay_offline(spec, cfg, bundle)
|
|
80
|
+
if result.status is not Status.SUCCESS:
|
|
81
|
+
report._add("build", "failed",
|
|
82
|
+
f"offline run did not succeed ({result.status.value}: {result.reason})")
|
|
83
|
+
return report
|
|
84
|
+
report._add("build", "ok", f"offline run succeeded → {result.value}")
|
|
85
|
+
|
|
86
|
+
# Stage 4 — record the track from the clean offline run.
|
|
87
|
+
track = record_track(events, task=spec.query, model=bundle.model)
|
|
88
|
+
track_path = str(Path(agent_dir) / "track.json")
|
|
89
|
+
track.save(track_path)
|
|
90
|
+
report.track_path = track_path
|
|
91
|
+
climbs = sorted({s.tier for s in track.steps})
|
|
92
|
+
tiers = (f"tiers {min(climbs)}→{max(climbs)}" if len(climbs) > 1
|
|
93
|
+
else f"tier {climbs[0]}" if climbs else "no tools")
|
|
94
|
+
report._add("track", "ok", f"recorded {len(track.steps)} steps ({tiers}) → {track_path}")
|
|
95
|
+
|
|
96
|
+
# Stage 5 — harden: score the track against perturbed fixtures and gate on it.
|
|
97
|
+
hr = await harden(spec, cfg, bundle)
|
|
98
|
+
report.harden = hr
|
|
99
|
+
score = hr.resilience
|
|
100
|
+
if not hr.grounding_load_bearing:
|
|
101
|
+
report._add("harden", "failed",
|
|
102
|
+
"a value-deletion control passed — grounding is not gating; the "
|
|
103
|
+
"resilience score is unreliable")
|
|
104
|
+
elif score < min_score:
|
|
105
|
+
report._add("harden", "failed",
|
|
106
|
+
f"resilience {score:.0%} below --min-score {min_score:.0%} "
|
|
107
|
+
f"({len(hr.findings)} brittle step(s) to fix)")
|
|
108
|
+
else:
|
|
109
|
+
report._add("harden", "ok",
|
|
110
|
+
f"resilience {score:.0%}; {len(hr.findings)} brittle step(s) noted")
|
|
111
|
+
return report
|