All publishing operations now use three-phase atomic approach: 1. Phase 1: Preparation - validate inputs, gather IPFS CIDs 2. Phase 2: IPFS operations - pin all content before any DB changes 3. Phase 3: DB transaction - all-or-nothing database commits Changes: ipfs_client.py: - Add IPFSError exception class - Add add_bytes() to store content on IPFS - Add add_json() to store JSON documents on IPFS - Add pin_or_raise() for synchronous pinning with error handling db.py: - Add transaction() context manager for atomic DB operations - Add create_asset_tx() for transactional asset creation - Add create_activity_tx() for transactional activity creation - Add get_asset_by_hash_tx() for lookup within transactions - Add asset_exists_by_name_tx() for existence check within transactions server.py: - Rewrite record_run: - Check L2 first for inputs, fall back to L1 - Store recipe JSON on IPFS with CID in provenance - Auto-register input assets if not already on L2 - All operations atomic - Rewrite publish_cache: - IPFS CID now required - Synchronous pinning before DB commit - Transaction for asset + activity - Rewrite _register_asset_impl: - IPFS CID now required - Synchronous pinning before DB commit - Transaction for asset + activity Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5.5 KiB
5.5 KiB