Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/workflows/design-decision-gate.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 33 additions & 8 deletions .github/workflows/design-decision-gate.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ max-turns: 30
model: claude-sonnet-4-6
engine:
id: claude
env:
GH_AW_HARNESS_STALL_WARNING_MS: "60000"
GH_AW_HARNESS_STALL_ERROR: "true"
safe-outputs:
add-comment:
max: 2
Expand Down Expand Up @@ -109,6 +112,8 @@ steps:
default_business_additions: 0,
requires_adr_by_default_volume: false,
file_count: 0,
diff_size_bytes: 0,
diff_truncated: false,
diff_available: false,
skip_reason: $skip_reason
}' > /tmp/gh-aw/agent/adr-prefetch-summary.json
Expand All @@ -123,19 +128,34 @@ steps:
> /tmp/gh-aw/agent/pr.json

gh api --paginate "repos/$EXPR_GITHUB_REPOSITORY/pulls/$PR_NUMBER/files?per_page=100" \
--jq '.[]' | jq -s '.' > /tmp/gh-aw/agent/pr-files.json
--jq '.[]' | jq -s '.' > /tmp/gh-aw/agent/pr-files-full.json

FILE_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-files.json)
FILE_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-files-full.json)

if [ "$FILE_COUNT" -gt 300 ]; then
echo "::warning::PR has $FILE_COUNT changed files (exceeds the 300-file GitHub diff API limit). Skipping full diff; file listing is available in pr-files.json."
printf '# Diff unavailable: PR has %s changed files (exceeds the 300-file GitHub diff API limit).\n# Use pr-files.json for the full file listing instead.\n' "$FILE_COUNT" \
> /tmp/gh-aw/agent/pr.diff
DIFF_SIZE_BYTES=0
DIFF_TRUNCATED=true
else
gh pr diff "$PR_NUMBER" \
--repo "$EXPR_GITHUB_REPOSITORY" \
> /tmp/gh-aw/agent/pr.diff
MAX_DIFF_BYTES=200000
jq -r '.[] | "diff --git a/\(.filename) b/\(.filename)\n--- a/\(.filename)\n+++ b/\(.filename)\n\(.patch // "# Patch unavailable")\n"' \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L143-144: native: hand-assembled diff text via jq template (diff --git/---/+++/patch) reinvents what gh pr diff already emits. gh pr diff "$PR_NUMBER" --repo "$EXPR_GITHUB_REPOSITORY" | head -c "$MAX_DIFF_BYTES", 0 hand-rolled diff formatting.

/tmp/gh-aw/agent/pr-files-full.json > /tmp/gh-aw/agent/pr.diff.full
DIFF_SIZE_BYTES=$(wc -c < /tmp/gh-aw/agent/pr.diff.full)
Comment on lines +143 to +145
if [ "$DIFF_SIZE_BYTES" -gt "$MAX_DIFF_BYTES" ]; then
head -c "$MAX_DIFF_BYTES" /tmp/gh-aw/agent/pr.diff.full > /tmp/gh-aw/agent/pr.diff
printf '\n# Diff truncated at %s bytes; use pr-files.json for file metadata instead.\n' "$MAX_DIFF_BYTES" \
>> /tmp/gh-aw/agent/pr.diff
rm /tmp/gh-aw/agent/pr.diff.full
DIFF_TRUNCATED=true
else
mv /tmp/gh-aw/agent/pr.diff.full /tmp/gh-aw/agent/pr.diff
DIFF_TRUNCATED=false
fi
fi
jq '[.[] | del(.patch)]' /tmp/gh-aw/agent/pr-files-full.json > /tmp/gh-aw/agent/pr-files.json
rm /tmp/gh-aw/agent/pr-files-full.json

if [ -f "$EXPR_GITHUB_WORKSPACE/.design-gate.yml" ]; then
cp "$EXPR_GITHUB_WORKSPACE/.design-gate.yml" /tmp/gh-aw/agent/design-gate-config.yml
Expand All @@ -155,6 +175,8 @@ steps:
--arg pr_number "$PR_NUMBER" \
--arg threshold "100" \
--argjson file_count "$FILE_COUNT" \
--argjson diff_size_bytes "$DIFF_SIZE_BYTES" \
--argjson diff_truncated "$DIFF_TRUNCATED" \
--argjson diff_available "$(jq -n --argjson fc "$FILE_COUNT" 'if $fc <= 300 then true else false end')" \
'{
pr_number: ($pr_number | tonumber),
Expand All @@ -164,6 +186,8 @@ steps:
default_business_additions: $default_business_additions,
requires_adr_by_default_volume: ($default_business_additions > ($threshold | tonumber)),
file_count: $file_count,
diff_size_bytes: $diff_size_bytes,
diff_truncated: $diff_truncated,
diff_available: $diff_available
}' > /tmp/gh-aw/agent/adr-prefetch-summary.json
evals:
Expand Down Expand Up @@ -224,11 +248,12 @@ Stop and emit a safe output **immediately** when any of the following is true:
2. If a pre-fetched file is missing or returns a permission error, fall back to the equivalent GitHub MCP tool immediately (do not retry the file read):
- Missing `pr.json` → `mcp__github__get_pull_request`
- Missing `pr-files.json` → `mcp__github__get_pull_request_files`
- Missing `pr.diff` → `mcp__github__get_pull_request_diff` (only if `diff_available` is `true` in the summary; if `false`, the diff exceeds the 300-file API limit — use `pr-files.json` instead and do **not** call the diff API)
- Missing `pr.diff` → `mcp__github__get_pull_request_diff` (only if `diff_available` is `true` and `diff_truncated` is `false` in the summary; otherwise use `pr-files.json` and do **not** call the diff API)
- Missing `adr-prefetch-summary.json` → compute manually from PR files and labels
3. Do **not** perform broad exploration. Only fetch extra data if a required field is missing from pre-fetched files.
4. Call exactly one final safe output action (`add-comment`, `push-to-pull-request-branch`, or `noop`) and then stop.
5. If you have enough evidence to decide, stop immediately. Do not gather optional data.
4. `pr.diff` is capped at 200,000 bytes. If `diff_truncated` is `true`, do not read it; use `pr-files.json` for file metadata and inspect only the specific changed files needed for the ADR decision.
5. Call exactly one final safe output action (`add-comment`, `push-to-pull-request-branch`, or `noop`) and then stop.
6. If you have enough evidence to decide, stop immediately. Do not gather optional data.

## Gate Quality Bar

Expand Down
4 changes: 3 additions & 1 deletion actions/setup/js/process_runner.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ function runProcess({ command, args, attempt, log, logArgs, env, postResultWatch
/** @type {NodeJS.Timeout | null} */
let stallWatchdogTimer = null;
const stallIntervalMs = Number.isFinite(Number(stallWarningIntervalMs)) ? Math.max(0, Number(stallWarningIntervalMs)) : resolveStallWarningIntervalMs(env ?? process.env);
const stallIsError = (env ?? process.env).GH_AW_HARNESS_STALL_ERROR === "true";
let stallWarnings = 0;
let stalledSinceMs = 0;

Expand Down Expand Up @@ -188,7 +189,8 @@ function runProcess({ command, args, attempt, log, logArgs, env, postResultWatch
if (stalledSinceMs === 0) stalledSinceMs = lastActivityAt;
stallWarnings++;
log(
`attempt ${attempt + 1}: stall watchdog: no output from '${command}' for ${formatDuration(idleMs)}` +
(stallIsError ? "::error::Agent CLI exceeded its no-output budget. " : "") +
`attempt ${attempt + 1}: stall watchdog: no output from '${command}' for ${formatDuration(idleMs)}` +
` (elapsed=${formatDuration(Date.now() - startTime)} pid=${child.pid ?? "unknown"} warnings=${stallWarnings})` +
` - the step may be hung${formatStepTimeoutBudget(startTime, env ?? process.env)}`
);
Expand Down
Loading
Loading