139 lines
9.7 KiB
Python
139 lines
9.7 KiB
Python
#!/usr/bin/env python3
|
||
"""СМЕТА ФАЗЫ Д ПО ЗАМЕРЕННЫМ ЦЕНАМ КЛЕТОК. $0.
|
||
|
||
⚠ Почему скриптом, а не в столбик. Пак 23 поднял потолок фазы, сославшись на «панель $1.844» —
|
||
это была ПРОЕКЦИЯ `--c-plan` по медианам, а фактическая панель стоила $1.798638 и влезала в
|
||
исходный потолок. Смета, посчитанная руками и не пере-снимаемая, ровно так и ошибается. Здесь
|
||
каждая цена берётся из СЫРЬЯ уже купленных клеток (медиана по модели и роли), и любой читатель
|
||
пере-считает командой.
|
||
|
||
Потолок фазы — САНКЦИЯ ВЛАДЕЛЬЦА $4.50 (10.08). История: промт называл $10.00, владелец при
|
||
запуске сказал $4.00, затем поднял до $4.50, когда приёмка другого модельного семейства нашла,
|
||
что дизайн не отвечает на H-1 и H-4, а починка стоит $0.48. ⚠ Сессия называла честным потолком
|
||
без стопов посреди фазы $4.80; владелец выбрал $4.50 — резерв $0.03, и срабатывание гарда есть
|
||
СТОП и вопрос владельцу, а не сокращение оси решением сессии.
|
||
|
||
Запуск: eval/.venv/bin/python eval/dovodka/plan.py [--gemini N]
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import collections
|
||
import json
|
||
import statistics as st
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
T = Path.home() / "books" / "tenant-panel"
|
||
E = Path.home() / "books" / "editor-tier"
|
||
# ⚠ Потолок берётся ИЗ КАССЫ, а не дублируется числом: копия отстала от санкций владельца
|
||
# ($4.50 против фактических $6.15) и смета сверялась с несуществующей границей.
|
||
import importlib.util as _il # noqa: E402
|
||
_sp = _il.spec_from_file_location("_money_d", Path(__file__).resolve().parent / "money_d.py")
|
||
_md = _il.module_from_spec(_sp); _sp.loader.exec_module(_md)
|
||
PACK_CEILING = _md.PACK_CEILING
|
||
|
||
|
||
def measured() -> dict[tuple[str, str], float]:
|
||
"""Медиана $/клетка по (роль, модель) из КУПЛЕННОГО сырья обоих паков."""
|
||
acc: dict[tuple[str, str], list[float]] = collections.defaultdict(list)
|
||
for d, pat in ((T, "tp*.json"), (E, "et-*.json")):
|
||
for f in d.glob(pat):
|
||
try:
|
||
r = json.loads(f.read_text(encoding="utf-8"))
|
||
except (ValueError, OSError):
|
||
continue
|
||
if isinstance(r, dict) and r.get("cost_usd") and r.get("model"):
|
||
acc[(r.get("role") or "?", r["model"])].append(r["cost_usd"])
|
||
return {k: st.median(v) for k, v in acc.items() if len(v) >= 3}
|
||
|
||
|
||
def main() -> int:
|
||
m = measured()
|
||
n_gem = 16
|
||
if "--gemini" in sys.argv:
|
||
n_gem = int(sys.argv[sys.argv.index("--gemini") + 1])
|
||
|
||
draft = m[("draft", "deepseek-v4-flash")]
|
||
edit = m[("edit", "deepseek-v4-pro")]
|
||
gem = 0.14702 # ЕДИНСТВЕННАЯ состоявшаяся клетка Ф3 эксп-22, n=1
|
||
# Производные цены армов edit-контура. Обоснование множителей — в отчёте §Д0; они ПРОГНОЗ,
|
||
# и расхождение с фактом печатается при закрытии фазы как сверка сметы.
|
||
fixer = 0.60 * edit # точечная починка: тот же вход, выход много короче
|
||
critic = 2.14 * edit # «поиск ≈2.14× переписа» — цифра из заказа владельца
|
||
onepass = edit # однопроходка: вход короче, размышление длиннее — вничью
|
||
|
||
print("ЗАМЕРЕННЫЕ ЦЕНЫ (медиана по сырью обоих паков):")
|
||
for k in (("draft", "deepseek-v4-flash"), ("edit", "deepseek-v4-pro"),
|
||
("editor3", "glm-5"), ("edit", "glm-5.2"), ("edit", "gpt-5.6-terra"),
|
||
("edit", "grok-4.5")):
|
||
if k in m:
|
||
print(f" {k[0]:8s}{k[1]:22s}${m[k]:.5f}")
|
||
print(f" {'edit':8s}{'gemini-3.1-pro-preview':22s}${gem:.5f} ⚠ n=1, "
|
||
f"{gem / edit:.0f}× боевого редактора")
|
||
print("\nПРОИЗВОДНЫЕ (прогноз, сверяется с фактом при закрытии):")
|
||
print(f" фиксер ${fixer:.5f} (0.60× переписа)")
|
||
print(f" критик ${critic:.5f} (2.14× переписа — множитель из заказа владельца)")
|
||
|
||
rows = []
|
||
# ── Д4 edit-контур zh, 32 единицы (16 эксп-22 + 16 эксп-23); A0 уже куплен обоими паками
|
||
n4 = 32
|
||
d4 = n4 * (fixer + onepass + (critic + fixer) + fixer) + 16 * fixer
|
||
rows.append(("ФД-A", "Д4 edit-контур zh: A1 флаги→фиксер · A2 однопроходка · "
|
||
f"A3 критик→фиксер · A4 канон-фиксер, n={n4} + свой пол", d4))
|
||
# ── Д3 en ось, 16 единиц
|
||
n3 = 16
|
||
d3 = (0.005 + 0.004 # банк-майнинг + проба контаминации
|
||
+ n3 * draft + n3 * edit + n3 * onepass
|
||
+ n3 * (fixer + critic + fixer) + n3 * edit) # два контура + пол
|
||
rows.append(("ФД-B", f"Д3 en→ru несущая: банк · контам-проба · связка · однопроходка · "
|
||
f"оба edit-контура · пол, n={n3}", d3))
|
||
# ── Д6 ja разведка, 9 единиц
|
||
n6 = 9
|
||
d6 = 0.004 + n6 * (draft + edit + onepass + edit)
|
||
rows.append(("ФД-C", f"Д6 ja→ru разведка: контам-проба · связка · однопроходка · пол, n={n6}",
|
||
d6))
|
||
# ── Д7 самооценка
|
||
rows.append(("ФД-D", "Д7 микро-проба самооценки жильцов по трём книгам", 0.05))
|
||
# ── Д1 gemini
|
||
# ⚠ ДВА АРМА, ЗАВЕДЁННЫЕ ПРИЁМКОЙ ДРУГОГО МОДЕЛЬНОГО СЕМЕЙСТВА. Без них фаза не отвечает на
|
||
# H-1 и H-4, и это нашёл не автор: H-1 говорит про «КАЧЕСТВЕННЫЙ черновик + точечный редактор»,
|
||
# а все армы Д4 ставят фиксер на flash-черновик — то есть на полумусор по самой гипотезе;
|
||
# H-4 про смену ПОРЯДКА жильцов на другой паре, а на en-оси редактор был ровно один.
|
||
rows.append(("ФД-F", "H-1: dspro-черновик эксп-22 (уже куплен, $0) + оба edit-контура, n=16 — "
|
||
"прямой носитель гипотезы «качественный черновик + точечный редактор»",
|
||
16 * (fixer + critic + fixer)))
|
||
rows.append(("ФД-G", "H-4: ВТОРОЙ редактор (glm-5) на en-оси поверх той же базы, n=16 — "
|
||
"без него порядок жильцов на en не проверяется вовсе", 16 * m[("editor3", "glm-5")]))
|
||
rows.append(("ФД-E", f"Д1 добивка gemini-3.1-pro-preview, {n_gem} клеток "
|
||
f"(503-отказы бесплатны, платим только за отгруженные)", n_gem * gem))
|
||
|
||
print(f"\n{'фаза':7s}{'что покупается':78s}{'смета':>9s}")
|
||
tot = 0.0
|
||
for tag, what, cost in rows:
|
||
tot += cost
|
||
print(f"{tag:7s}{what[:78]:78s}{cost:9.3f}")
|
||
print(f"{'ИТОГО':7s}{'':78s}{tot:9.3f} при потолке ${PACK_CEILING:.2f}")
|
||
free = PACK_CEILING - tot
|
||
print(f"{'резерв':7s}{'':78s}{free:9.3f}")
|
||
if free < 0:
|
||
print("\n⛔ НЕ ВЛЕЗАЕТ. Резать ось или кандидата решением сессии ЗАПРЕЩЕНО "
|
||
"(промт, анти-лень) —\n это СТОП и вопрос владельцу.")
|
||
elif free < 0.30:
|
||
print("\n⚠ Резерв меньше 8% пакета. Ре-гены эхо-мины и ретраи в паках 22/23 съедали "
|
||
"до +16%\n сверх сметы фазы — при таком резерве первый же эхо-ре-ген упрётся "
|
||
"в потолок.")
|
||
|
||
print(f"\n⚠ ДОЛЯ ОДНОЙ МОДЕЛИ: Д1 = ${n_gem * gem:.2f} = "
|
||
f"{n_gem * gem / PACK_CEILING * 100:.0f}% всего пакета фазы.")
|
||
print(f" Цена клетки ${gem:.5f} против ${edit:.5f} у боевого редактора — это "
|
||
f"${gem * 1500:.0f} за книгу\n при ${edit * 1500:.0f} у боевого. Продуктовым выбором "
|
||
"модель быть не может ни при каком исходе;\n ценность замера — закрыть гипотезу "
|
||
"эксп-04 «аутлаер прозы», не более.")
|
||
print(f"\n Сколько единиц Д1 влезает при остальном плане: "
|
||
f"{int((PACK_CEILING - (tot - n_gem * gem) - 0.35) / gem)} "
|
||
"(с резервом $0.35 на ре-гены).")
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|