========== YENİ KOMUT | 17.09.2026 12:13:51 ==========
========== YENİ KOMUT | 17.09.2026 12:13:51 ==========
/home/hermes/.hermes/skills/media/shorts-core/SKILL.md
222-- hazır master + ses için FFmpeg direct mux ve `-c:v copy`;
223-- video stream hash kontrolü;
224-- probe, decode, black/freeze ve loudness QA;
225-- tek final contact sheet;
226-- TTS, bbox, visual master, final mux ve deterministic QA cache.
227-
228-Değişmeyen manifest ve girdilerde cache'i yeniden kullan. Aynı deterministic adımı doğrulama amacıyla tekrar üretme.
229-
230-Helper için geçici tek-seferlik bbox scripti, yeni Python ortamı veya yeniden keşfedilmiş FFmpeg/Montaj yolları oluşturma. Helper teknik olarak başarısız olursa yalnız hatalı bileşeni teşhis et.
231-
232-### Faz 3 — Tek görsel QA geçidi
233-
234:Deterministic pipeline PASS verdikten sonra yalnız final contact sheet'i `vision_analyze` ile değerlendir.
235-
236-Kontrol et:
237-
238-- gerçek 9:16 tam ekran;
239-- siyah/boş bant veya yanlış crop;
240-- en fazla iki satır altyazı ve safe area;
241-- Türkçe yazım/karakterler;
242-- gerçek footage önceliği ve shot çeşitliliği;
243-- render bozulması;
244-- anlatım ile görselin semantik uyumu.
245-
246-PASS ise yeniden render veya ikinci contact sheet üretme.
/home/hermes/.hermes/plugins/shorts-production-guard/__init__.py
407- return None
408- prospective_text = (
409- current_text.replace(old, new)
410- if args.get("replace_all") is True
411- else current_text.replace(old, new, 1)
412- )
413-
414- prospective = json.loads(prospective_text)
415- if _runtime_proof_fingerprint(prospective) != current_fp:
416- return _block(
417- "Shorts production guard: PROOF_FREEZE — accepted proof is locked. "
418- "Do not change creative_intent, proof candidates, or selected footage/casting "
419: "after Vision PASS. Continue with TTS/render/final QA using the accepted plan. "
420- "A genuine proof failure must be handled before acceptance, not by reopening "
421- "the proof loop after PASS."
422- )
423- except Exception:
424- return None
425- return None
426-
427-
428-def _proof_attempt_state_path(image_path: Path, pending: Optional[dict] = None) -> Path:
429- """Use one attempt ledger per canonical proof receipt, not per proofN workdir."""
430- if isinstance(pending, dict):
431- receipt = pending.get("receipt")
--
660- if (
661- int(proof_state.get("failed_attempts") or 0) >= 2
662- and current_fingerprint
663- and proof_state.get("last_fingerprint") == current_fingerprint
664- ):
665- return _block(
666- "Shorts production guard: PROOF_STRATEGY_EXHAUSTED — this proof strategy "
667- "already failed initial review plus one repair. Do not retry Vision on the "
668- "same accepted candidates/casting. Materially change the proof footage or "
669- "casting, rerun proof-check, and continue the production autonomously."
670- )
671-
672: # Content identity matters more than filename: a repaired final_contact_sheet
673- # at the same path is new evidence and must be allowed to be judged again.
674- try:
675- image_identity = _sha_file(image_path.resolve())
676- except Exception:
677- image_identity = str(image_path)
678-
679- normalized_question = re.sub(r"\s+", " ", question).strip()
680- sig_raw = json.dumps(
681- {
682- "session": session_id,
683- "image": image_identity,
684- "question": normalized_question,
--
774- except Exception:
775- return text
776-
777-
778-def _update_repair_state_from_vision(
779- image_path: Path,
780- question: str,
781- result: Any,
782- session_id: str,
783- turn_id: str,
784- tool_call_id: str,
785-) -> None:
786: if image_path.name != "final_contact_sheet.jpg":
787- return
788- state_path = image_path.parent / "repair_state.json"
789- if not state_path.exists():
790- return
791- try:
792- state = json.loads(state_path.read_text(encoding="utf-8"))
793- except Exception:
794- return
795- if state.get("state") not in {"repair_attempted", "verification_pending"}:
796- return
797- token = str(state.get("repair_token") or "")
798- if not token or f"HERMES_REPAIR_VERIFY::{token}" not in question:
root@213-238-170-219:~#