You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Problem. Doc 09 step 3b (PR #132): CoW must become the first venue adapter, and the flagship modules must prove the pool. The nullisLabs composable-cow fork makes the poll path structured and non-reverting, so the off-chain side becomes a generic ComposableCoW poller with no handler-specific logic.
Scope. The cow-venue module as a distinct venue speaker built on three WIT layers: the CoW venue wit (shepherd:cow), the venue-agnostic intent wit (nexum:intent, nexum:value-flow, nexum:adapter), and the runtime host wit (nexum:host). Three feature slices: default (body types + borsh codec); client (typed client + orderbook submit-error classification for modules); adapter (the nexum:adapter component). The poll reads the structured PollResult (generator/fill/filledAmount/restriction) from the contract's non-reverting poll(); the revert-decode lives on-chain in BaseConditionalOrder.poll(), so the module does no selector decode. The verdict is GeneratorResultCode + bytes4 reasonCode (log only); scheduling comes from nextPollTimestamp/waitUntil. Golden vectors published per the venue-is-a-spec rule. twap-monitor generalises into a handler-agnostic ccow-monitor (TWAP survives as watch scope + vectors, not code); ethflow keeps its observe path. The legacy cow cone retires: wit/shepherd-cow, shepherd-cow-host, shepherd-sdk/src/cow.
Two classification concerns, kept separate. (a) The ComposableCoW POLL verdict comes from the contract (GeneratorResultCode + bytes4 reasonCode); there is no off-chain table and no string reasons. (b) The CoW ORDERBOOK-API submit-error errorType-to-action table (#236) stays as data: it classifies the REST POST /api/v1/orders response, orthogonal to the poll. #236 owns (b) and folds #75/#48/#121 once; it does not own poll decode.
Drive any handler (new scope, the substance of the generic monitor). (i) IOrderModule sandbox for NEEDS_INPUT offchainInput acquisition (content-hash-gated, output distrusted); (ii) IOrderManifest enumeration + offchainInput = abi.encode(uint256 index) fan-out for multi-order-per-poll; (iii) merkle-payload discovery (fetch mirror, recompute root, reconstruct proofs). None is needed for the five flagship handlers (none emits PollNeedsOffchainInput), so all three are follow-on.
Dependencies. Intent core (#137), keeper (#135), and #133 (appData hash-only lands first so the adapter never grows the redundant GET).
Notes. appData travels as the 32-byte on-chain hash; the flagship venue surface is submit + status only. Rename set from the fork: getTradeableOrder to generateOrder; PollTryAtEpoch(uint,string) to PollTryAtTimestamp(uint,bytes4); PollNever removed (use OrderNotValid); getTradeableOrderWithSignature returns PollResult, not (order,bytes); poll no longer reverts. Pool accepted(receipt) is post-submit, so the pre-submit idempotency guard is preserved only if the order UID stays a cow-venue guest concern feeding the SDK journal.
Next-train plan (stage only)
Current state. The legacy CoW surface is the pre-adapter path on the OLD upstream reverting poll (shepherd-cow-host + shepherd-sdk/src/cow/*). The fork's structured-poll registry is 2.0.0-dev, deployed on no chain, so the poll wire cannot retarget yet. This train stages the dependency-light body and table work.
W2 (gated on fork deployments/networks.json non-empty on a shepherd chain, off the grant clock): replace the adapter with a direct checkOrder/getTradeableOrderWithSignature to PollResult struct-read; delete shepherd-sdk/src/cow/composable.rs and the twap poll body (poll_one/decode_return/classify_poll_error, TryAtEpoch/TryOnBlock); regenerate golden vectors against bytes4 reasonCode + PollResult.
Deferred to follow-on train (Waves G to J): cow adapter component + timeout middleware (resolves #41) + requires-signing submit; golden vectors + conformance kit wiring; [[adapters]] bundling; re-point twap and ethflow onto the pool; retire the legacy cow cone (wit/shepherd-cow, shepherd-cow-host, shepherd-sdk/src/cow); #138 owns this deletion, #136's workspace-member removal sequences after it.
Merge gate: the poll retarget (shepherd-sdk/src/cow/composable.rs, twap-monitor/src/strategy.rs, ADR-0006) must not merge until the fork's deployments/networks.json is non-empty on a shepherd target chain.
Problem. Doc 09 step 3b (PR #132): CoW must become the first venue adapter, and the flagship modules must prove the pool. The nullisLabs composable-cow fork makes the poll path structured and non-reverting, so the off-chain side becomes a generic ComposableCoW poller with no handler-specific logic.
Scope. The cow-venue module as a distinct venue speaker built on three WIT layers: the CoW venue wit (
shepherd:cow), the venue-agnostic intent wit (nexum:intent,nexum:value-flow,nexum:adapter), and the runtime host wit (nexum:host). Three feature slices: default (body types + borsh codec); client (typed client + orderbook submit-error classification for modules); adapter (thenexum:adaptercomponent). The poll reads the structuredPollResult(generator/fill/filledAmount/restriction) from the contract's non-revertingpoll(); the revert-decode lives on-chain inBaseConditionalOrder.poll(), so the module does no selector decode. The verdict isGeneratorResultCode+bytes4 reasonCode(log only); scheduling comes fromnextPollTimestamp/waitUntil. Golden vectors published per the venue-is-a-spec rule. twap-monitor generalises into a handler-agnosticccow-monitor(TWAP survives as watch scope + vectors, not code); ethflow keeps its observe path. The legacy cow cone retires:wit/shepherd-cow,shepherd-cow-host,shepherd-sdk/src/cow.Two classification concerns, kept separate. (a) The ComposableCoW POLL verdict comes from the contract (
GeneratorResultCode+bytes4 reasonCode); there is no off-chain table and no string reasons. (b) The CoW ORDERBOOK-API submit-errorerrorType-to-action table (#236) stays as data: it classifies the REST POST/api/v1/ordersresponse, orthogonal to the poll. #236 owns (b) and folds #75/#48/#121 once; it does not own poll decode.Drive any handler (new scope, the substance of the generic monitor). (i)
IOrderModulesandbox forNEEDS_INPUToffchainInput acquisition (content-hash-gated, output distrusted); (ii)IOrderManifestenumeration +offchainInput = abi.encode(uint256 index)fan-out for multi-order-per-poll; (iii) merkle-payload discovery (fetch mirror, recompute root, reconstruct proofs). None is needed for the five flagship handlers (none emitsPollNeedsOffchainInput), so all three are follow-on.Dependencies. Intent core (#137), keeper (#135), and #133 (appData hash-only lands first so the adapter never grows the redundant GET).
Notes. appData travels as the 32-byte on-chain hash; the flagship venue surface is submit + status only. Rename set from the fork:
getTradeableOrdertogenerateOrder;PollTryAtEpoch(uint,string)toPollTryAtTimestamp(uint,bytes4);PollNeverremoved (useOrderNotValid);getTradeableOrderWithSignaturereturnsPollResult, not(order,bytes); poll no longer reverts. Poolaccepted(receipt)is post-submit, so the pre-submit idempotency guard is preserved only if the order UID stays a cow-venue guest concern feeding the SDK journal.Next-train plan (stage only)
Current state. The legacy CoW surface is the pre-adapter path on the OLD upstream reverting poll (
shepherd-cow-host+shepherd-sdk/src/cow/*). The fork's structured-poll registry is2.0.0-dev, deployed on no chain, so the poll wire cannot retarget yet. This train stages the dependency-light body and table work.Children this train:
Backoffproducer; folds twap-monitor retries unknown revert selectors every block forever #75/twap-monitor orphaned gate markers leak on decode-failure path #48/sdk+twap: treat DuplicatedOrder as already-submitted; add errorType→retry classification #121, sole owner) · Wave F · M · deps cow: scaffold cow-venue crate default slice (intent body types + borsh IntentBody codec) #235Migration waves (HYBRID; the poll retarget is gated on fork deploy):
ConditionalSource::Outcometo aVerdictmirroringGeneratorResultCode+ hints; land refactor(twap-monitor): port poll loop onto keeper #240's twap poll behind a namedLegacyRevertAdapter(maps the 5 deployed-1.x selectors toVerdict). twap posts on testnet through the target seam. Grant M2 met.deployments/networks.jsonnon-empty on a shepherd chain, off the grant clock): replace the adapter with a directcheckOrder/getTradeableOrderWithSignaturetoPollResultstruct-read; deleteshepherd-sdk/src/cow/composable.rsand the twap poll body (poll_one/decode_return/classify_poll_error,TryAtEpoch/TryOnBlock); regenerate golden vectors againstbytes4 reasonCode+PollResult.IOrderModule,IOrderManifestfan-out, merkle discovery.Deferred to follow-on train (Waves G to J): cow adapter component + timeout middleware (resolves #41) + requires-signing submit; golden vectors + conformance kit wiring;
[[adapters]]bundling; re-point twap and ethflow onto the pool; retire the legacy cow cone (wit/shepherd-cow,shepherd-cow-host,shepherd-sdk/src/cow); #138 owns this deletion, #136's workspace-member removal sequences after it.Merge gate: the poll retarget (
shepherd-sdk/src/cow/composable.rs,twap-monitor/src/strategy.rs, ADR-0006) must not merge until the fork'sdeployments/networks.jsonis non-empty on a shepherd target chain.Blocked by: #137, #135, #133.