mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-09-19 02:56:17 +00:00
Two secondary adapters plus the spec mapping they share, and the first real payoff of the port boundary: test_schedule_fakes.py becomes a contract suite that runs all 31 cases against both the in-memory doubles and the SQL adapters on a real sqlite file. A rule stated in a port docstring now has to hold for both, and a divergence is a failure rather than a surprise in production. The queries come over unchanged. The claim statement's FOR UPDATE SKIP LOCKED and both protect_terminal conditional writes are this module's concurrency contract, not style, and the IntegrityError translation in add() is what lets the service collapse a lost active-slot race into the same outcome as its own non-atomic fast path. Two things the adapters own that the domain deliberately does not. The claiming process's identity is generated here, because who claimed a task is an identity rather than a rule and nothing reads it back. And `Unsupported schedule_type` is raised by the mapping, because ScheduleSpec only accepts the enum -- structural checks belong to the boundary, value rules to __post_init__, and both surface as the same domain error so the router maps one family. _to_domain introduces a failure mode the legacy repository did not have: a row whose stored schedule no longer parses. Single-row reads let it propagate; list reads skip and log, so one corrupt row cannot 500 an entire listing. The contract suite reaches past the port in exactly one place -- seeding a task that already carries a claim, a shape claim_due would never produce -- and says so where it does.