@@ -3,7 +3,6 @@ name: Engine Conformance Agy (Experimental)
33description : Bounded production authentication, AWF, MCP and safe-output gate for experimental Agy.
44on :
55 workflow_dispatch :
6- workflow_call :
76permissions :
87 contents : read
98concurrency :
1514 agent :
1615 timeout-minutes : 10
1716max-ai-credits : 5
18- max-turn-cache-misses : 12
1917features :
2018 gh-aw-detection : false
2119engine :
@@ -32,91 +30,8 @@ safe-outputs:
3230 report-as-issue : false
3331 missing-tool :
3432 create-issue : false
35- mcp-servers :
36- agy-native :
37- type : http
38- url : " http://host.docker.internal:${{ steps.mcp-scripts-start.outputs.port }}"
39- headers :
40- Authorization : " ${{ steps.mcp-scripts-start.outputs.api_key }}"
41- allowed :
42- - native-challenge
43- mcp-scripts :
44- native-challenge :
45- description : Return a fresh nonce and record evidence for the native Agy MCP transport.
46- inputs :
47- file_nonce :
48- type : string
49- required : true
50- description : The fileNonce from the conformance fixture.
51- env :
52- CONFORMANCE_STATE : ${{ runner.temp }}/engine-conformance
53- script : |
54- const crypto = require("node:crypto");
55- const fs = require("node:fs");
56- const path = require("node:path");
57- const host = process.env.CONFORMANCE_STATE;
58- if (!host) throw new Error("CONFORMANCE_STATE is missing");
59- const expected = JSON.parse(fs.readFileSync(path.join(host, "expected.json"), "utf8"));
60- if (file_nonce !== expected.fileNonce) throw new Error("The fixture nonce does not match");
61- const receipt = { fileNonce: file_nonce, toolNonce: crypto.randomBytes(24).toString("hex") };
62- fs.writeFileSync(path.join(host, "native-receipt.json"), JSON.stringify(receipt), { mode: 0o600 });
63- return { toolNonce: receipt.toolNonce };
64- post-steps :
65- - name : Assert native Agy MCP transport and inference accounting
66- if : always()
67- env :
68- CONFORMANCE_STATE : ${{ runner.temp }}/engine-conformance
69- run : |
70- set -euo pipefail
71- node <<'JS'
72- const assert = require("node:assert/strict");
73- const fs = require("node:fs");
74- const path = require("node:path");
75- const host = process.env.CONFORMANCE_STATE;
76- const receipt = JSON.parse(fs.readFileSync(path.join(host, "native-receipt.json"), "utf8"));
77- const expected = JSON.parse(fs.readFileSync(path.join(host, "expected.json"), "utf8"));
78- assert.equal(receipt.fileNonce, expected.fileNonce);
79- assert.match(receipt.toolNonce, /^[a-f0-9]{48}$/);
80- const entries = fs.readFileSync("/tmp/gh-aw/agent-stdio.log", "utf8").split(/\r?\n/).flatMap(line => {
81- try { return [JSON.parse(line)]; } catch { return []; }
82- });
83- const tools = entries.filter(entry => entry.event === "step_update" && entry.step_update?.step_type === "tool");
84- assert.ok(tools.some(entry => /agy[-_]native.*native[-_]challenge/.test(entry.step_update.tool_info?.name || "")),
85- "The challenge must be called through the native MCP client, not its CLI wrapper");
86- const terminal = entries.filter(entry => entry.event === "result").at(-1)?.result;
87- assert.equal(terminal?.status, "SUCCESS");
88- assert.ok(Number.isSafeInteger(terminal?.num_turns) && terminal.num_turns > 0);
89- assert.ok(terminal?.usage?.input_tokens > 0);
90- assert.ok(terminal?.usage?.output_tokens > 0);
91- assert.ok(entries.some(entry => entry.event === "init" && entry.init?.model === "gemini-3.8-flash-medium"));
92- const usage = {};
93- for (const name of ["input_tokens", "output_tokens", "thinking_tokens", "cache_read_tokens", "total_tokens"]) {
94- const count = terminal.usage[name];
95- if (count !== undefined) {
96- assert.ok(Number.isSafeInteger(count) && count >= 0, `Invalid ${name}`);
97- usage[name] = count;
98- }
99- }
100- fs.writeFileSync(path.join(host, "native-report.json"),
101- JSON.stringify({ status: "passed", nativeMCP: true, inference: true, usage }, null, 2),
102- { mode: 0o600 });
103- JS
104- - name : Upload native Agy conformance evidence
105- if : always()
106- uses : actions/upload-artifact@v7.0.2
107- with :
108- name : agy-production-native-conformance
109- path : ${{ runner.temp }}/engine-conformance/native-report.json
110- retention-days : 2
111- if-no-files-found : error
11233imports :
113- - uses : shared/engine-conformance.md
114- with :
115- engine-id : agy
34+ - shared/agy-conformance.md
11635---
11736
118- Execute the imported engine configuration conformance suite once.
119-
120- Also call the ` native-challenge ` tool through the native MCP server ` agy-native ` ,
121- using the actual fixture ` fileNonce ` . Do not call ` mcpscripts native-challenge `
122- or substitute a shell/HTTP request; the checker requires a native MCP tool event.
37+ Execute the imported Agy conformance gate once.
0 commit comments