refactor: consolidate skill docs, add anti-drift tests, and apply audit fixes
DLO-13: Restructure vlm-library-workflow skill as safety contract layer. - Rewrite SKILL.md (69 lines): safety contract, execution threshold semantics, six-step high-risk loop, decision rules, phase skeleton - Delete redundant references (cli-reference, workflow, command-recipes, dev-guide) - Add triage.md (failure mapping + preflight) and dev-map.md (module→test mapping) - Add tests/test_docs_consistency.py: 78 parametrized tests verifying documented vlm commands exist in CLI registry - Add CSV path mismatch test to test_plan_review.py (4th safety gate path) - Delete vlm-expert.skill (Gemini package, 7 months stale) and README Gemini section DLO-2 audit fixes: rate limiter injection, symmetric quarantine categories, review-plan safety gates, parser improvements, planner validation. CLI modularization: commands/ directory with one module per command group.
This commit is contained in:
@@ -565,3 +565,70 @@ def _format_duration(duration_seconds: float) -> str:
|
||||
parts.append(f"{seconds}s")
|
||||
|
||||
return " ".join(parts)
|
||||
|
||||
|
||||
def completeness_from_analysis(analysis_data: dict) -> list[SeasonCompleteness]:
|
||||
"""Build SeasonCompleteness records from analysis JSON."""
|
||||
result: list[SeasonCompleteness] = []
|
||||
for row in analysis_data.get("completeness", []) or []:
|
||||
result.append(
|
||||
SeasonCompleteness(
|
||||
series_title=row["series_title"],
|
||||
season=row["season"],
|
||||
episodes_found=row["episodes_found"],
|
||||
episodes_missing=row["episodes_missing"],
|
||||
)
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
def duplicate_groups_from_analysis(analysis_data: dict) -> list[DuplicateGroup]:
|
||||
"""Build DuplicateGroup records from analysis JSON."""
|
||||
groups: list[DuplicateGroup] = []
|
||||
for dup in analysis_data.get("duplicates", []) or []:
|
||||
identity_data = dup["identity"]
|
||||
if identity_data["type"] == "movie":
|
||||
identity = MovieIdentity(
|
||||
title=identity_data["title"],
|
||||
year=identity_data.get("year"),
|
||||
confidence=1.0,
|
||||
needs_review=False,
|
||||
original_filename="",
|
||||
)
|
||||
else:
|
||||
identity = SeriesIdentity(
|
||||
title=identity_data["title"],
|
||||
season=identity_data.get("season"),
|
||||
episodes=identity_data.get("episodes", []),
|
||||
confidence=1.0,
|
||||
needs_review=False,
|
||||
original_filename="",
|
||||
)
|
||||
|
||||
quality_by_path = {
|
||||
str(item.get("path", "")): item for item in dup.get("quality_comparison", [])
|
||||
}
|
||||
files: list[VideoFile] = []
|
||||
for file_path in dup.get("files", []) or []:
|
||||
quality = quality_by_path.get(str(file_path), {})
|
||||
files.append(
|
||||
VideoFile(
|
||||
path=Path(file_path),
|
||||
filename=Path(file_path).name,
|
||||
size_bytes=int(quality.get("size_bytes", 0) or 0),
|
||||
modified_timestamp=datetime.now(timezone.utc),
|
||||
category="",
|
||||
resolution=quality.get("resolution"),
|
||||
codec=quality.get("codec"),
|
||||
duration_seconds=quality.get("duration_seconds"),
|
||||
bitrate_kbps=quality.get("bitrate_kbps"),
|
||||
)
|
||||
)
|
||||
groups.append(
|
||||
DuplicateGroup(
|
||||
identity=identity,
|
||||
files=files,
|
||||
quality_comparison=dup.get("quality_comparison", []),
|
||||
)
|
||||
)
|
||||
return groups
|
||||
|
||||
Reference in New Issue
Block a user