Why
llama.cpp's OpenAI-compatible server rejects any tool JSON Schema whose pattern is not anchored at both ends (^...$). The workflow tool's workflow_id parameter is branded as Dag.ID, whose Effect Schema filter Schema.isStartsWith("dag") serializes to pattern: "^dag" — start-anchored only. Every request carrying the workflow tool is rejected with JSON schema conversion failed: Pattern must start with '^' and end with '$', so an opencode session pointed at a llama.cpp backend fails on the first message.
Evidence: mitm capture of the tool payloads showed 5 unanchored ^dag patterns (one per workflow-tool parameter referencing Dag.ID); server log shows the corresponding AI_APICallError.
Scope
packages/schema/src/dag-event.ts — make DagID's filter serialize to a fully anchored pattern (e.g. ^dag.*$) with identical validation semantics (starts-with).
- Regression test asserting the JSON Schema serialization of
Dag.ID is both-start-and-end anchored.
Acceptance
- Generated tool parameter schemas for
Dag.ID produce a pattern matching ^...\$ form accepted by llama.cpp (both anchors present).
- Existing DagID validation semantics unchanged (any string starting with
dag_ still valid).
specgit finish exits 0.
Why
llama.cpp's OpenAI-compatible server rejects any tool JSON Schema whose
patternis not anchored at both ends (^...$). The workflow tool'sworkflow_idparameter is branded asDag.ID, whose Effect Schema filterSchema.isStartsWith("dag")serializes topattern: "^dag"— start-anchored only. Every request carrying the workflow tool is rejected withJSON schema conversion failed: Pattern must start with '^' and end with '$', so an opencode session pointed at a llama.cpp backend fails on the first message.Evidence: mitm capture of the tool payloads showed 5 unanchored
^dagpatterns (one per workflow-tool parameter referencingDag.ID); server log shows the correspondingAI_APICallError.Scope
packages/schema/src/dag-event.ts— makeDagID's filter serialize to a fully anchored pattern (e.g.^dag.*$) with identical validation semantics (starts-with).Dag.IDis both-start-and-end anchored.Acceptance
Dag.IDproduce a pattern matching^...\$form accepted by llama.cpp (both anchors present).dag_still valid).specgit finishexits 0.