kaizen-3c-cli 1.0.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.
- cli/__init__.py +2 -0
- cli/approval.py +72 -0
- cli/bench/__init__.py +13 -0
- cli/bench/value_add_fingerprint.py +327 -0
- cli/commands/__init__.py +2 -0
- cli/commands/bench.py +333 -0
- cli/commands/decompose.py +233 -0
- cli/commands/demo.py +312 -0
- cli/commands/init.py +299 -0
- cli/commands/mcp_serve.py +116 -0
- cli/commands/memsafe_roadmap.py +562 -0
- cli/commands/migrate_plan.py +586 -0
- cli/commands/priors.py +86 -0
- cli/commands/recompose.py +234 -0
- cli/commands/resume.py +399 -0
- cli/commands/status.py +130 -0
- cli/commands/web.py +104 -0
- cli/config.py +278 -0
- cli/demo_assets/README.md +68 -0
- cli/demo_assets/__init__.py +2 -0
- cli/demo_assets/slugify_demo.tar.gz +0 -0
- cli/events.py +248 -0
- cli/main.py +140 -0
- cli/mcp_server/__init__.py +20 -0
- cli/mcp_server/server.py +543 -0
- cli/mcp_server/tests/__init__.py +0 -0
- cli/mcp_server/tests/test_server.py +224 -0
- cli/output.py +241 -0
- cli/pipeline/__init__.py +9 -0
- cli/pipeline/decompose_v2.py +746 -0
- cli/pipeline/oneshot_baseline.py +229 -0
- cli/pipeline/recompose_v2.py +520 -0
- cli/pipeline/roundtrip_diff.py +126 -0
- cli/pipeline/specialist_review.py +162 -0
- cli/review.py +246 -0
- cli/tests/__init__.py +0 -0
- cli/tests/test_approval.py +182 -0
- cli/tests/test_bench.py +261 -0
- cli/tests/test_config.py +244 -0
- cli/tests/test_demo.py +214 -0
- cli/tests/test_events.py +118 -0
- cli/tests/test_init.py +211 -0
- cli/tests/test_resume.py +259 -0
- cli/tests/test_review.py +333 -0
- cli/web_server/__init__.py +14 -0
- cli/web_server/routes/__init__.py +2 -0
- cli/web_server/routes/adr.py +33 -0
- cli/web_server/routes/decompose.py +110 -0
- cli/web_server/routes/memsafe.py +138 -0
- cli/web_server/routes/migrate.py +133 -0
- cli/web_server/routes/priors.py +50 -0
- cli/web_server/routes/providers.py +44 -0
- cli/web_server/routes/recompose.py +105 -0
- cli/web_server/routes/runs.py +69 -0
- cli/web_server/routes/status.py +55 -0
- cli/web_server/routes/version.py +15 -0
- cli/web_server/server.py +94 -0
- cli/web_server/settings.py +53 -0
- cli/web_server/sse.py +101 -0
- cli/web_server/static/.build-info +4 -0
- cli/web_server/static/assets/index-BsmHrNwi.js +187 -0
- cli/web_server/static/assets/index-BsmHrNwi.js.map +1 -0
- cli/web_server/static/assets/index-FELcRPb3.css +1 -0
- cli/web_server/static/index.html +14 -0
- cli/web_server/tests/__init__.py +0 -0
- cli/web_server/tests/test_integration.py +123 -0
- cli/web_server/tests/test_routes.py +189 -0
- cli/web_server/tests/test_sse.py +168 -0
- kaizen_3c_cli-1.0.0.dist-info/METADATA +123 -0
- kaizen_3c_cli-1.0.0.dist-info/RECORD +75 -0
- kaizen_3c_cli-1.0.0.dist-info/WHEEL +5 -0
- kaizen_3c_cli-1.0.0.dist-info/entry_points.txt +2 -0
- kaizen_3c_cli-1.0.0.dist-info/licenses/LICENSE +193 -0
- kaizen_3c_cli-1.0.0.dist-info/licenses/NOTICE +119 -0
- kaizen_3c_cli-1.0.0.dist-info/top_level.txt +1 -0
cli/__init__.py
ADDED
cli/approval.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""User approval prompt for interactive CLI checkpoints.
|
|
3
|
+
|
|
4
|
+
Provides a single interactive approval function for commands that have optional
|
|
5
|
+
stages (e.g., recompose after generating a roadmap/plan). Handles non-TTY
|
|
6
|
+
environments (CI, piped input) gracefully.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def is_tty() -> bool:
|
|
15
|
+
"""Return True if stdin is connected to a terminal (interactive session).
|
|
16
|
+
|
|
17
|
+
Wrapped in try/except for odd environments (e.g., some test harnesses).
|
|
18
|
+
"""
|
|
19
|
+
try:
|
|
20
|
+
return sys.stdin.isatty()
|
|
21
|
+
except Exception:
|
|
22
|
+
return False
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def approval_prompt(
|
|
26
|
+
message: str,
|
|
27
|
+
*,
|
|
28
|
+
yolo: bool = False,
|
|
29
|
+
default: bool = False,
|
|
30
|
+
) -> bool:
|
|
31
|
+
"""Prompt the user for approval, with graceful fallbacks for non-TTY.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
message: The prompt message to display (e.g. "Continue to recompose?").
|
|
35
|
+
yolo: If True, return True immediately without prompting (opt-out mode).
|
|
36
|
+
default: The return value if stdin is not a TTY or user hits enter.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
True if user approves (or yolo=True), False otherwise.
|
|
40
|
+
|
|
41
|
+
Behavior:
|
|
42
|
+
- If yolo=True: return True immediately (no prompt).
|
|
43
|
+
- If stdin is not a TTY: log "(non-interactive; skipping prompt, proceeding=<default>)"
|
|
44
|
+
to stderr and return `default`.
|
|
45
|
+
- Otherwise: print message + prompt to stderr, read a line from stdin.
|
|
46
|
+
- "y" or "yes" (case-insensitive) -> True
|
|
47
|
+
- Empty line -> `default`
|
|
48
|
+
- Anything else -> False
|
|
49
|
+
- Ctrl-C (KeyboardInterrupt) -> print "aborted" and return False.
|
|
50
|
+
"""
|
|
51
|
+
if yolo:
|
|
52
|
+
return True
|
|
53
|
+
|
|
54
|
+
if not is_tty():
|
|
55
|
+
sys.stderr.write(f"(non-interactive; skipping prompt, proceeding={default})\n")
|
|
56
|
+
return default
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
prompt_suffix = " [Y/n] " if default else " [y/N] "
|
|
60
|
+
sys.stderr.write(message + prompt_suffix)
|
|
61
|
+
sys.stderr.flush()
|
|
62
|
+
|
|
63
|
+
line = sys.stdin.readline().strip().lower()
|
|
64
|
+
|
|
65
|
+
if not line:
|
|
66
|
+
return default
|
|
67
|
+
if line in ("y", "yes"):
|
|
68
|
+
return True
|
|
69
|
+
return False
|
|
70
|
+
except KeyboardInterrupt:
|
|
71
|
+
sys.stderr.write("\naborted\n")
|
|
72
|
+
return False
|
cli/bench/__init__.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Vendored benchmark analysis scripts.
|
|
3
|
+
|
|
4
|
+
These are copied verbatim from `Kaizen-3C/benchmarks/commit0/baselines/`
|
|
5
|
+
to keep `kaizen bench` self-contained — no separate clone, no PyPI
|
|
6
|
+
dependency. Sync periodically via scripts/sync-bench-vendor.py
|
|
7
|
+
(forthcoming) when upstream changes.
|
|
8
|
+
|
|
9
|
+
Vendored modules:
|
|
10
|
+
- value_add_fingerprint: per-cell architectural weakness matrix
|
|
11
|
+
- compare_baselines: per-arch aggregate comparisons
|
|
12
|
+
- (more to add as they prove useful at the CLI surface)
|
|
13
|
+
"""
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# VENDORED FROM: Kaizen-3C/benchmarks/commit0/baselines/value_add_fingerprint.py
|
|
3
|
+
# Sync manually; kept self-contained so `pip install kaizen-3c-cli` works without
|
|
4
|
+
# requiring a separate clone of the benchmarks repo.
|
|
5
|
+
"""Value-add architectural fingerprint table.
|
|
6
|
+
|
|
7
|
+
For each (architecture x model x library) cell:
|
|
8
|
+
value_add_pp = arch_pass_rate - single_shot_LLM_pass_rate (same model)
|
|
9
|
+
value_add_$_pp = arch_cost / max(value_add_pp, 0.01)
|
|
10
|
+
llm_lean = arch_cost / single_shot_LLM_cost (same model, same lib)
|
|
11
|
+
|
|
12
|
+
Reads from benchmarks/commit0/results/. Outputs to stdout.
|
|
13
|
+
Also flags architectural weakness signatures per ADR-0063 §weakness_fingerprints.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
# Default results directory — relative to the original script location in the
|
|
22
|
+
# benchmarks repo. main() accepts an override via results_dir parameter.
|
|
23
|
+
R = Path(__file__).resolve().parents[2] / "commit0" / "results"
|
|
24
|
+
|
|
25
|
+
LIBS = ["wcwidth", "deprecated", "cachetools", "voluptuous", "portalocker",
|
|
26
|
+
"pyjwt", "chardet", "tinydb", "simpy", "imapclient", "parsel",
|
|
27
|
+
"marshmallow", "cookiecutter", "babel", "jinja", "minitorch"]
|
|
28
|
+
FLOOR = {"chardet", "marshmallow", "babel", "jinja", "minitorch"}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def loadj(p: Path) -> dict:
|
|
32
|
+
return json.loads(p.read_text()) if p.exists() else {}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def lib_passrate(per_lib: dict, lib: str) -> tuple[int, int, float | None]:
|
|
36
|
+
"""Return (passed, attempted, rate or None if not run)."""
|
|
37
|
+
d = (per_lib or {}).get(lib, {}) or {}
|
|
38
|
+
c = d.get("counts") or d.get("final_counts") or {}
|
|
39
|
+
p, f, e = c.get("passed", 0), c.get("failed", 0), c.get("errors", 0)
|
|
40
|
+
a = p + f + e
|
|
41
|
+
if a == 0 and not c:
|
|
42
|
+
return 0, 0, None # not run
|
|
43
|
+
return p, a, ((100 * p / a) if a else 0)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def lib_cost(per_lib: dict, lib: str, source_provider: str) -> float | None:
|
|
47
|
+
"""Cost from per-library JSON. Some baselines store cost differently."""
|
|
48
|
+
d = (per_lib or {}).get(lib, {}) or {}
|
|
49
|
+
if not d:
|
|
50
|
+
return None
|
|
51
|
+
# Prefer pre-computed cost
|
|
52
|
+
if "totals" in d and isinstance(d["totals"], dict):
|
|
53
|
+
c = d["totals"].get("cost_usd")
|
|
54
|
+
if c is not None:
|
|
55
|
+
return c
|
|
56
|
+
# B2: compute from tokens
|
|
57
|
+
fresh_in = d.get("input_tokens", 0)
|
|
58
|
+
out = d.get("output_tokens", 0)
|
|
59
|
+
cached = d.get("cached_input_tokens", 0)
|
|
60
|
+
if source_provider == "anthropic":
|
|
61
|
+
return (fresh_in * 3 + out * 15) / 1_000_000
|
|
62
|
+
return ((fresh_in - cached) * 1.25 + cached * 0.125 + out * 10) / 1_000_000
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def oh_status(report: dict, lib: str) -> tuple[str, float | None]:
|
|
66
|
+
"""OH instance status: RES / no / FAIL. Cost from report metrics."""
|
|
67
|
+
if not report:
|
|
68
|
+
return "FAIL", None
|
|
69
|
+
if lib in report.get("resolved_ids", []):
|
|
70
|
+
return "RES", None
|
|
71
|
+
if lib in report.get("unresolved_ids", []):
|
|
72
|
+
return "no", None
|
|
73
|
+
if lib in report.get("completed_ids", []):
|
|
74
|
+
return "?", None
|
|
75
|
+
return "FAIL", None
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def oh_lib_cost_from_jsonl(jsonl: Path, lib: str) -> float | None:
|
|
79
|
+
if not jsonl.exists():
|
|
80
|
+
return None
|
|
81
|
+
for line in jsonl.read_text(encoding="utf-8", errors="replace").splitlines():
|
|
82
|
+
if not line.strip():
|
|
83
|
+
continue
|
|
84
|
+
try:
|
|
85
|
+
obj = json.loads(line)
|
|
86
|
+
except json.JSONDecodeError:
|
|
87
|
+
continue
|
|
88
|
+
iid = obj.get("instance_id") or ""
|
|
89
|
+
if iid.endswith(lib):
|
|
90
|
+
return (obj.get("metrics") or {}).get("accumulated_cost", 0)
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def merge_oh_dirs(results_root: Path, *dir_names: str) -> dict:
|
|
95
|
+
"""Merge multiple OH result dirs into one (lib -> (status, cost))."""
|
|
96
|
+
out = {}
|
|
97
|
+
for name in dir_names:
|
|
98
|
+
d = results_root / name
|
|
99
|
+
rep_p = d / "output.report.json"
|
|
100
|
+
jsonl_p = d / "output.jsonl"
|
|
101
|
+
if not rep_p.exists():
|
|
102
|
+
continue
|
|
103
|
+
rep = json.loads(rep_p.read_text())
|
|
104
|
+
for lib in (rep.get("completed_ids", []) or []):
|
|
105
|
+
status, _ = oh_status(rep, lib)
|
|
106
|
+
cost = oh_lib_cost_from_jsonl(jsonl_p, lib) if jsonl_p.exists() else None
|
|
107
|
+
out[lib] = (status, cost)
|
|
108
|
+
return out
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def kd_per_lib(results_root: Path, provider: str) -> dict:
|
|
112
|
+
"""Load KD per-lib JSONs (separate files, not aggregated dict)."""
|
|
113
|
+
out = {}
|
|
114
|
+
for lib in LIBS:
|
|
115
|
+
p = results_root / f"{lib}_kaizen_delta_{provider}.json"
|
|
116
|
+
if p.exists():
|
|
117
|
+
d = json.loads(p.read_text())
|
|
118
|
+
if "final_counts" in d:
|
|
119
|
+
d["counts"] = d["final_counts"]
|
|
120
|
+
out[lib] = d
|
|
121
|
+
return out
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def compute_cell(arch_per_lib: dict, lib: str, single_shot_per_lib: dict,
|
|
125
|
+
source_provider: str) -> dict | None:
|
|
126
|
+
"""For KD-style architectures with full per-lib pass-rate."""
|
|
127
|
+
p, a, rate = lib_passrate(arch_per_lib, lib)
|
|
128
|
+
sp, sa, srate = lib_passrate(single_shot_per_lib, lib)
|
|
129
|
+
if rate is None or srate is None:
|
|
130
|
+
return None
|
|
131
|
+
cost = lib_cost(arch_per_lib, lib, source_provider) or 0
|
|
132
|
+
s_cost = lib_cost(single_shot_per_lib, lib, source_provider) or 0.001
|
|
133
|
+
value_add_pp = rate - srate
|
|
134
|
+
value_add_dollar_pp = (cost / max(value_add_pp, 0.01)) if value_add_pp > 0 else None
|
|
135
|
+
llm_lean = cost / max(s_cost, 0.001)
|
|
136
|
+
return {
|
|
137
|
+
"passed": p, "attempted": a, "rate": rate,
|
|
138
|
+
"cost": cost, "value_add_pp": value_add_pp,
|
|
139
|
+
"value_add_dollar_pp": value_add_dollar_pp, "llm_lean": llm_lean,
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def compute_oh_cell(oh_dict: dict, lib: str, single_shot_per_lib: dict,
|
|
144
|
+
source_provider: str) -> dict | None:
|
|
145
|
+
"""For OH (binary RES/no/FAIL)."""
|
|
146
|
+
if lib not in oh_dict:
|
|
147
|
+
return None
|
|
148
|
+
status, cost = oh_dict[lib]
|
|
149
|
+
cost = cost or 0
|
|
150
|
+
sp, sa, srate = lib_passrate(single_shot_per_lib, lib)
|
|
151
|
+
if srate is None:
|
|
152
|
+
return None
|
|
153
|
+
s_cost = lib_cost(single_shot_per_lib, lib, source_provider) or 0.001
|
|
154
|
+
# OH's pass-rate is binary: RES = 100, anything else = unknown
|
|
155
|
+
if status == "RES":
|
|
156
|
+
rate = 100.0
|
|
157
|
+
value_add_pp = 100 - srate
|
|
158
|
+
elif status == "no":
|
|
159
|
+
rate = None
|
|
160
|
+
value_add_pp = None
|
|
161
|
+
else:
|
|
162
|
+
rate = None
|
|
163
|
+
value_add_pp = None
|
|
164
|
+
value_add_dollar_pp = (
|
|
165
|
+
(cost / max(value_add_pp, 0.01))
|
|
166
|
+
if (value_add_pp and value_add_pp > 0)
|
|
167
|
+
else None
|
|
168
|
+
)
|
|
169
|
+
llm_lean = cost / max(s_cost, 0.001)
|
|
170
|
+
return {
|
|
171
|
+
"status": status, "rate": rate, "cost": cost,
|
|
172
|
+
"value_add_pp": value_add_pp,
|
|
173
|
+
"value_add_dollar_pp": value_add_dollar_pp, "llm_lean": llm_lean,
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def fmt_cell(c: dict | None, kind: str = "kd") -> str:
|
|
178
|
+
if c is None:
|
|
179
|
+
return f"{' --':>16}"
|
|
180
|
+
if kind == "oh":
|
|
181
|
+
if c['status'] == "RES":
|
|
182
|
+
return f"RES +{c['value_add_pp']:>3.0f}pp x{c['llm_lean']:>4.0f}"
|
|
183
|
+
if c['status'] == "no":
|
|
184
|
+
return f" no ? x{c['llm_lean']:>4.0f}"
|
|
185
|
+
return "FAIL -- --"
|
|
186
|
+
# KD-style
|
|
187
|
+
va = c['value_add_pp']
|
|
188
|
+
sign = "+" if va >= 0 else ""
|
|
189
|
+
return f"{c['rate']:>3.0f}% {sign}{va:>+4.0f}pp x{c['llm_lean']:>4.1f}"
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def run_fingerprint(results_root: Path) -> None:
|
|
193
|
+
"""Compute and print the full value-add fingerprint table."""
|
|
194
|
+
# Load all baselines
|
|
195
|
+
b2s = loadj(results_root / "aggregate_lite_single_shot_sonnet.json").get("per_library", {})
|
|
196
|
+
b2g = loadj(results_root / "aggregate_lite_single_shot_openai.json").get("per_library", {})
|
|
197
|
+
b3s = loadj(results_root / "aggregate_lite_reflexion_sonnet.json").get("per_library", {})
|
|
198
|
+
b3g = loadj(results_root / "aggregate_lite_reflexion_openai.json").get("per_library", {})
|
|
199
|
+
|
|
200
|
+
kds = kd_per_lib(results_root, "anthropic")
|
|
201
|
+
kdg = kd_per_lib(results_root, "openai")
|
|
202
|
+
|
|
203
|
+
# OH merged across all subset dirs
|
|
204
|
+
oh_s = merge_oh_dirs(results_root, "b6_partial_pass1", "b6_4cheap_sonnet", "b6_t3_sonnet")
|
|
205
|
+
oh_g = merge_oh_dirs(results_root, "b6_partial_gpt54_3libs", "b6_4cheap_gpt54", "b6_10missing_gpt54")
|
|
206
|
+
|
|
207
|
+
print("=" * 145)
|
|
208
|
+
print("VALUE-ADD FINGERPRINT — each cell shows: pass-rate, value_add_pp vs same-model B2, llm_lean (cost ratio vs B2)")
|
|
209
|
+
print("=" * 145)
|
|
210
|
+
hdr = f"{'lib':12} {'F?':>2} | {'KD-S':>16} {'KD-G':>16} | {'OH-S':>17} {'OH-G':>17}"
|
|
211
|
+
print(hdr)
|
|
212
|
+
print("-" * len(hdr))
|
|
213
|
+
|
|
214
|
+
floor_unlocks = []
|
|
215
|
+
big_wins = []
|
|
216
|
+
big_losses = []
|
|
217
|
+
oh_resolved = []
|
|
218
|
+
|
|
219
|
+
for lib in LIBS:
|
|
220
|
+
f = "*" if lib in FLOOR else " "
|
|
221
|
+
kds_cell = compute_cell(kds, lib, b2s, "anthropic")
|
|
222
|
+
kdg_cell = compute_cell(kdg, lib, b2g, "openai")
|
|
223
|
+
ohs_cell = compute_oh_cell(oh_s, lib, b2s, "anthropic")
|
|
224
|
+
ohg_cell = compute_oh_cell(oh_g, lib, b2g, "openai")
|
|
225
|
+
print(
|
|
226
|
+
f"{lib:12} {f:>2} | "
|
|
227
|
+
f"{fmt_cell(kds_cell, 'kd'):>16} {fmt_cell(kdg_cell, 'kd'):>16} | "
|
|
228
|
+
f"{fmt_cell(ohs_cell, 'oh'):>17} {fmt_cell(ohg_cell, 'oh'):>17}"
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
# Collect findings
|
|
232
|
+
for cell, label in [(kds_cell, f"KD-S {lib}"), (kdg_cell, f"KD-G {lib}")]:
|
|
233
|
+
if cell and cell['value_add_pp'] is not None:
|
|
234
|
+
if cell['value_add_pp'] >= 10:
|
|
235
|
+
big_wins.append((label, cell))
|
|
236
|
+
if cell['value_add_pp'] <= -10:
|
|
237
|
+
big_losses.append((label, cell))
|
|
238
|
+
if lib in FLOOR and cell['rate'] > 0:
|
|
239
|
+
floor_unlocks.append((label, cell))
|
|
240
|
+
for cell, label in [(ohs_cell, f"OH-S {lib}"), (ohg_cell, f"OH-G {lib}")]:
|
|
241
|
+
if cell and cell.get('status') == 'RES':
|
|
242
|
+
oh_resolved.append((label, cell))
|
|
243
|
+
if lib in FLOOR:
|
|
244
|
+
floor_unlocks.append((label + " (RES)", cell))
|
|
245
|
+
|
|
246
|
+
print()
|
|
247
|
+
print("Legend:")
|
|
248
|
+
print(" KD cells: pass% +pp vs same-model B2 xN llm_lean (cost ratio)")
|
|
249
|
+
print(" OH cells: RES = resolved 100% / no = unresolved / FAIL = didn't complete")
|
|
250
|
+
print(" +/- pp: value-add over the LLM's single-shot baseline (same model)")
|
|
251
|
+
print(" llm_lean: cost ratio -- 1x means 'spent same as just calling the LLM once'")
|
|
252
|
+
print()
|
|
253
|
+
|
|
254
|
+
# Architectural-weakness signatures
|
|
255
|
+
print("=" * 100)
|
|
256
|
+
print("ARCHITECTURAL-WEAKNESS SIGNATURES (per ADR-0063 §weakness_fingerprints)")
|
|
257
|
+
print("=" * 100)
|
|
258
|
+
|
|
259
|
+
print()
|
|
260
|
+
print("OH WEAKNESS — high llm_lean for low/negative value-add")
|
|
261
|
+
print("(cells where OH spent much more than the LLM and didn't resolve):")
|
|
262
|
+
for lib in LIBS:
|
|
263
|
+
cell = compute_oh_cell(oh_s, lib, b2s, "anthropic")
|
|
264
|
+
if cell and cell['llm_lean'] > 5 and cell.get('status') in ("no", "FAIL"):
|
|
265
|
+
print(
|
|
266
|
+
f" OH-S {lib:13} {cell['status']:>4} "
|
|
267
|
+
f"llm_lean={cell['llm_lean']:>5.0f}x cost=${cell['cost']:.2f}"
|
|
268
|
+
)
|
|
269
|
+
cell = compute_oh_cell(oh_g, lib, b2g, "openai")
|
|
270
|
+
if cell and cell['llm_lean'] > 5 and cell.get('status') in ("no", "FAIL"):
|
|
271
|
+
print(
|
|
272
|
+
f" OH-G {lib:13} {cell['status']:>4} "
|
|
273
|
+
f"llm_lean={cell['llm_lean']:>5.0f}x cost=${cell['cost']:.2f}"
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
print()
|
|
277
|
+
print("KD WEAKNESS — negative value-add (per-file regen damaged working code):")
|
|
278
|
+
for label, cell in big_losses:
|
|
279
|
+
print(
|
|
280
|
+
f" {label:18} rate={cell['rate']:>3.0f}% "
|
|
281
|
+
f"value_add={cell['value_add_pp']:+.0f}pp "
|
|
282
|
+
f"cost=${cell['cost']:.2f} llm_lean={cell['llm_lean']:.1f}x"
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
print()
|
|
286
|
+
print("FLOOR-LIB UNLOCKS (only baseline >0% on a floor lib):")
|
|
287
|
+
for label, cell in floor_unlocks:
|
|
288
|
+
rate = cell.get('rate', 100 if cell.get('status') == 'RES' else None)
|
|
289
|
+
print(f" {label:30} rate={rate} cost=${cell['cost']:.2f}")
|
|
290
|
+
|
|
291
|
+
print()
|
|
292
|
+
print("BIG WINS (KD value-add >= 10pp):")
|
|
293
|
+
for label, cell in big_wins:
|
|
294
|
+
print(
|
|
295
|
+
f" {label:18} rate={cell['rate']:>3.0f}% "
|
|
296
|
+
f"value_add=+{cell['value_add_pp']:.0f}pp "
|
|
297
|
+
f"cost=${cell['cost']:.2f} llm_lean={cell['llm_lean']:.1f}x"
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def main(results_dir: Path | None = None) -> int:
|
|
302
|
+
"""Programmatic entry point. Returns exit code (0 = success).
|
|
303
|
+
|
|
304
|
+
Parameters
|
|
305
|
+
----------
|
|
306
|
+
results_dir:
|
|
307
|
+
Override the default results directory. When *None* the module falls
|
|
308
|
+
back to the ``R`` global (which points at the benchmarks repo's own
|
|
309
|
+
``commit0/results/`` tree when run from the monorepo, or wherever
|
|
310
|
+
``kaizen bench fingerprint --results`` points).
|
|
311
|
+
"""
|
|
312
|
+
global R
|
|
313
|
+
if results_dir is not None:
|
|
314
|
+
R = Path(results_dir).resolve()
|
|
315
|
+
|
|
316
|
+
results_root = R
|
|
317
|
+
if not results_root.exists():
|
|
318
|
+
print(f"Results directory not found: {results_root}")
|
|
319
|
+
print("Pass --results <dir> pointing at a commit0 results directory.")
|
|
320
|
+
return 1
|
|
321
|
+
|
|
322
|
+
run_fingerprint(results_root)
|
|
323
|
+
return 0
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
if __name__ == "__main__":
|
|
327
|
+
raise SystemExit(main())
|
cli/commands/__init__.py
ADDED