Problem
The semantic contract lint reads the task text for an order id, a recipient, a "send" instruction and prior refund ids using regular expressions tuned to the three PhantomBench templates (packages/benchmark/src/validate/). It is honest about what it checks, but it is the single most domain-specific piece of the system, and it is the first thing that breaks on a new task shape.
Proposal
Introduce a TaskAdapter interface that turns a task instruction plus a domain schema into typed task facts ({ orderIds, recipients, monetaryAmounts, prohibitedTargets, ... }), with the refund-operations adapter as the first implementation. The lint consumes facts, never raw text.
Done when
- The existing lint behaviour is preserved on all 24 fixtures (
pnpm benchmark:validate, pnpm benchmark:validate-hard).
- A second adapter can be registered without touching the lint.
- An ADR under
docs/decisions/ records the interface.
See docs/limitations.md, "Known weaknesses in the implementation".
Problem
The semantic contract lint reads the task text for an order id, a recipient, a "send" instruction and prior refund ids using regular expressions tuned to the three PhantomBench templates (
packages/benchmark/src/validate/). It is honest about what it checks, but it is the single most domain-specific piece of the system, and it is the first thing that breaks on a new task shape.Proposal
Introduce a
TaskAdapterinterface that turns a task instruction plus a domain schema into typed task facts ({ orderIds, recipients, monetaryAmounts, prohibitedTargets, ... }), with the refund-operations adapter as the first implementation. The lint consumes facts, never raw text.Done when
pnpm benchmark:validate,pnpm benchmark:validate-hard).docs/decisions/records the interface.See
docs/limitations.md, "Known weaknesses in the implementation".