@@ -104,6 +104,52 @@ Test workflow.`,
104104 `\"claude\":{\"enabled\":false}` ,
105105 },
106106 },
107+ {
108+ name : "engine object form resolves to the claude runtime" ,
109+ frontmatter : `---
110+ on: workflow_dispatch
111+ engine:
112+ id: claude
113+ model: claude-3-5-sonnet-20241022
114+ network:
115+ allowed:
116+ - defaults
117+ hosted-web:
118+ allowed:
119+ - docs.github.com
120+ ---
121+
122+ # Test
123+ Test workflow.` ,
124+ wantContains : []string {
125+ `\"hostedWeb\"` ,
126+ `\"claude\":{\"enabled\":true,\"allowedDomains\":[\"docs.github.com\"]}` ,
127+ },
128+ },
129+ {
130+ name : "inline runtime definition resolves to the codex runtime" ,
131+ frontmatter : `---
132+ on: workflow_dispatch
133+ engine:
134+ runtime:
135+ id: codex
136+ provider:
137+ model: gpt-5
138+ network:
139+ allowed:
140+ - defaults
141+ hosted-web:
142+ blocked:
143+ - example.com
144+ ---
145+
146+ # Test
147+ Test workflow.` ,
148+ wantContains : []string {
149+ `\"hostedWeb\"` ,
150+ `\"codex\":{\"enabled\":true,\"blockedDomains\":[\"example.com\"]}` ,
151+ },
152+ },
107153 {
108154 name : "no network configuration omits hostedWeb entirely" ,
109155 frontmatter : `---
@@ -224,3 +270,86 @@ Test workflow.`
224270 t .Errorf ("Expected error to reference network.hosted-web, got: %v" , err )
225271 }
226272}
273+
274+ // TestCompileWorkflow_HostedWebRejectsInvalidFrontmatter verifies that the
275+ // frontmatter schema rejects unsupported hosted-web syntax at compile time,
276+ // covering the removed `enabled` field and the AWF domain-list constraints.
277+ func TestCompileWorkflow_HostedWebRejectsInvalidFrontmatter (t * testing.T ) {
278+ longDomain := strings .Repeat (strings .Repeat ("a" , 60 )+ "." , 4 ) + "example.com"
279+
280+ tests := []struct {
281+ name string
282+ hostedWeb string
283+ wantMessage string
284+ }{
285+ {
286+ name : "enabled field is not part of the frontmatter contract" ,
287+ hostedWeb : ` hosted-web:
288+ enabled: true
289+ allowed:
290+ - docs.github.com` ,
291+ wantMessage : "hosted-web" ,
292+ },
293+ {
294+ name : "duplicate allowed domains are rejected" ,
295+ hostedWeb : ` hosted-web:
296+ allowed:
297+ - docs.github.com
298+ - docs.github.com` ,
299+ wantMessage : "are equal" ,
300+ },
301+ {
302+ name : "allowed domains longer than 253 characters are rejected" ,
303+ hostedWeb : ` hosted-web:
304+ allowed:
305+ - ` + longDomain ,
306+ wantMessage : "maxLength" ,
307+ },
308+ {
309+ name : "duplicate blocked domains are rejected" ,
310+ hostedWeb : ` hosted-web:
311+ blocked:
312+ - example.com
313+ - example.com` ,
314+ wantMessage : "are equal" ,
315+ },
316+ {
317+ name : "blocked domains longer than 253 characters are rejected" ,
318+ hostedWeb : ` hosted-web:
319+ blocked:
320+ - ` + longDomain ,
321+ wantMessage : "maxLength" ,
322+ },
323+ }
324+
325+ for _ , tt := range tests {
326+ t .Run (tt .name , func (t * testing.T ) {
327+ frontmatter := `---
328+ on: workflow_dispatch
329+ engine: claude
330+ network:
331+ allowed:
332+ - defaults
333+ ` + tt .hostedWeb + `
334+ ---
335+
336+ # Test
337+ Test workflow.`
338+
339+ tmpDir := testutil .TempDir (t , "hosted-web-invalid-frontmatter-test" )
340+ testFile := filepath .Join (tmpDir , "test-workflow.md" )
341+ if err := os .WriteFile (testFile , []byte (frontmatter ), 0644 ); err != nil {
342+ t .Fatalf ("Failed to write workflow file: %v" , err )
343+ }
344+
345+ compiler := NewCompiler ()
346+ err := compiler .CompileWorkflow (testFile )
347+ if err == nil {
348+ t .Fatal ("Expected compilation to fail for invalid hosted-web frontmatter" )
349+ }
350+ if ! strings .Contains (err .Error (), tt .wantMessage ) {
351+ t .Errorf ("Expected error to contain %q, got: %v" , tt .wantMessage , err )
352+ }
353+ })
354+ }
355+ }
0 commit comments