Files
ECC/skills/taste-application/tests/test_provenance.py
T
928c1dea72 feat(tasteforge): package reusable workflows and preserve native edits (#3033)
* feat: bundle standalone taste distillation and application workflows

* docs: fix imported taste skill markdown lint

* docs: align Turkish agent catalog with taste skills

* refactor: make ECC the canonical reusable video engine

* fix: preserve video duration when applying image overlays

* fix: preserve background colors in image compositing

* fix: report best-effort duration targets and shortfalls

* feat: ship verified Fusion presets with compatibility provenance

* feat(tasteforge): preserve native edits in application bundles

* feat(tasteforge): compile local preservation without hosted input

* fix: update js-yaml to patched 4.3.2

* test: report bounded Stop wrapper failure diagnostics

* fix(tasteforge): fail closed on unsafe output names, missing overlays and cadence

- cli: default report and spec paths are derived from pack name and profile
  genre; require the manifest's name pattern before using either as a
  filename part so a traversal string cannot write outside cwd/out.
- apply_local: a pack without cadence.json, or with no measured shots and
  no explicit mean_shot, raises instead of silently planning 1.0s shots and
  reporting a measured cadence.
- legacy apply: a missing overlay aborts before any paid upload; forge()
  would have rejected it after every take was generated.
- requirements-live: pin fal-client>=0.13.0, the first release whose
  subscribe() accepts client_timeout.

Addresses the five P1 findings from the independent review of #3033.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015fxHRsydPqEcYngGbqkgt1

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 15:31:36 +01:00

83 lines
3.1 KiB
Python

"""Failing-first tests for tasteforge provenance and provider-reference policy.
Contract:
- exact lineage of the recovered TasteForge sources is recorded as data;
- a provider workflow may only ever be referenced, never claimed as saved;
- the Claude cloud session is recorded honestly (selected, transcript absent).
"""
from __future__ import annotations
import sys
import unittest
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1] / "scripts"
sys.path.insert(0, str(REPO_ROOT))
from tasteforge import provenance # noqa: E402
CANONICAL = "recovered/tasteforge-flow-20260818"
LATEST_SHA = "ef06a606d3b528fbd939b05fadc25bf6674073a1e05a01e3aa6b9c9416fd6284"
SESSION = "redacted-local-session"
class LineageTests(unittest.TestCase):
def test_lineage_report_names_canonical_source(self):
report = provenance.lineage_report()
self.assertEqual(report["canonical_source"]["path"], CANONICAL)
self.assertTrue(report["canonical_source"]["read_only"])
def test_all_five_generations_recorded_with_digests(self):
gens = provenance.lineage_report()["generations"]
self.assertEqual(len(gens), 5)
latest = [g for g in gens if g["archive"] == "tasteforge (4).zip"][0]
self.assertEqual(latest["sha256"], LATEST_SHA)
self.assertEqual(latest["status"], "latest")
for g in gens[:-1]:
self.assertEqual(g["status"], "prior")
def test_generation_deltas_explain_lineage(self):
gens = provenance.lineage_report()["generations"]
self.assertTrue(all(g.get("delta") for g in gens))
latest = gens[-1]
self.assertIn("grade", latest["delta"])
def test_claude_session_recorded_honestly(self):
sess = provenance.lineage_report()["claude_session"]
self.assertEqual(sess["id"], SESSION)
self.assertFalse(sess["transcript_available"])
self.assertTrue(sess["selection_evidence_local"])
def test_lineage_report_passes_schema(self):
from tasteforge import schema
problems = schema.validate(
provenance.lineage_report(), schema.PROVENANCE_SCHEMA
)
self.assertEqual(problems, [])
class ProviderReferenceTests(unittest.TestCase):
def test_provider_reference_is_pointer_only(self):
ref = provenance.provider_reference("fal")
self.assertEqual(ref["kind"], "provider-workflow-reference")
self.assertEqual(ref["provider"], "fal")
self.assertTrue(ref["reference_only"])
self.assertFalse(ref["persisted_workflow_state"])
self.assertFalse(ref["authorizes_execution"])
def test_saved_workflow_state_is_rejected(self):
record = {"kind": "provider-workflow-reference", "provider": "fal",
"reference_only": True, "persisted_workflow_state": True,
"authorizes_execution": False}
with self.assertRaises(provenance.SavedWorkflowClaimError):
provenance.assert_no_saved_provider_workflow([record])
def test_clean_records_pass(self):
provenance.assert_no_saved_provider_workflow([provenance.provider_reference("fal")])
if __name__ == "__main__":
unittest.main()