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
24 changes: 23 additions & 1 deletion examples/dark-factory/coder/entrypoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,25 @@ function runCoder(repoDir) {
// Inherit stdio so the coder CLI's own output + errors stream into the pod
// logs (kubectl logs), instead of being swallowed by execFileSync's exception.
const opts = { cwd: repoDir, env, stdio: "inherit", maxBuffer: 64 * 1024 * 1024 };
const prompt = `Implement the change described in ${WORKSPACE}/SPEC.md. Build and run unit tests until green. Commit your work.`;
// The coder also writes a concise, human-readable summary of WHAT it changed to
// artifacts/description.md β€” this becomes the "Changes" section of the PR body
// (in addition to the verification section). Keep it short: what changed + why,
// as reviewer-facing markdown bullets.
const descPath = `${WORKSPACE}/artifacts/description.md`;
const prompt =
`Implement the change described in ${WORKSPACE}/SPEC.md. Build and run unit tests until green. Commit your work. ` +
`Then write a concise description of the changes you made (what changed and why, as a few markdown bullet points, ` +
`reviewer-facing β€” no preamble) to ${descPath}.`;
if (ENGINE === "kiro") {
// Kiro CLI headless β€” the coder image carries the `kiro` binary; it reads the
// same Bifrost/Bedrock env above. --headless drives it non-interactively.
// Append the description instruction so kiro produces the same artifact.
console.log("[coder] engine=kiro (kiro run --headless)");
try {
fs.appendFileSync(`${WORKSPACE}/SPEC.md`,
`\n\n---\n\n## After implementing\n\nWrite a concise description of the changes you made ` +
`(what changed and why, a few reviewer-facing markdown bullets, no preamble) to ${descPath}.\n`);
} catch { /* non-fatal */ }
return execFileSync("kiro", ["run", "--headless", "--spec", `${WORKSPACE}/SPEC.md`], opts);
}
console.log("[coder] engine=claude (claude -p)");
Expand Down Expand Up @@ -429,9 +443,17 @@ async function main() {
? "- ⏳ **Security review (AWS Security Agent):** _queued (DevOps cleared)…_"
: "- ⬜ **Security review (AWS Security Agent):** _waiting on DevOps clearance_";
}
// Coder-authored description of the changes (artifacts/description.md). Shown
// as a "Changes" section ahead of the verification block. Falls back to a
// neutral line if the coder didn't produce one, so the PR body is never empty.
const desc = readSecret(`${WORKSPACE}/artifacts/description.md`);
const changesSection = desc
? ["### πŸ“ Changes", "", desc, ""]
: ["### πŸ“ Changes", "", "_Implemented per the linked issue; see the diff for details._", ""];
const prBody = [
`Closes #${ISSUE}.`,
"",
...changesSection,
"<!-- dark-factory:status -->",
"### 🏭 Dark Factory β€” verification",
`- βœ… **Build + unit tests:** ${test.summary}`,
Expand Down
38 changes: 32 additions & 6 deletions gitops/addons/charts/dark-factory/scripts/security-agent.sh
Original file line number Diff line number Diff line change
Expand Up @@ -95,27 +95,53 @@ JOBID="$(aws securityagent start-code-review-job --region "$AWS_REGION" \
log "codeReviewJobId=${JOBID} β€” polling (timeout ${POLL_TIMEOUT}s)..."

# ── 4. Poll to completion ────────────────────────────────────────────────────
# The job's `status` field lags well behind the actual analysis: the AWS Security
# Agent GitHub App posts its findings comment on the PR (e.g. "No issues identified")
# minutes before batch-get-code-review-jobs flips to COMPLETED. Polling status alone
# therefore blocks this (advisory) step for the full timeout even though the result
# is already known. So we ALSO probe list-findings each iteration: once it returns a
# well-formed result (findingsSummaries key present), the review has produced output
# and we can proceed immediately β€” this is the early-exit that avoids the long wait.
DEADLINE=$(( $(date +%s) + POLL_TIMEOUT ))
STATUS="IN_PROGRESS"
DONE=""
: > "$WORK/findings.json"
while [ "$(date +%s)" -lt "$DEADLINE" ]; do
STATUS="$(aws securityagent batch-get-code-review-jobs --region "$AWS_REGION" \
--agent-space-id "$AGENT_SPACE_ID" --code-review-job-ids "$JOBID" \
--query 'codeReviewJobs[0].status' --output text 2>/dev/null || echo IN_PROGRESS)"
log "job status=${STATUS}"
case "$STATUS" in
COMPLETED|SUCCEEDED) break ;;
COMPLETED|SUCCEEDED) DONE="status"; break ;;
FAILED|STOPPED|ERROR) log "review job ${STATUS}"; post_status "error" "security: review job ${STATUS}"; exit 0 ;;
esac
# Early-exit: findings ready before status flips? (App bot already posted them.)
if aws securityagent list-findings --region "$AWS_REGION" \
--agent-space-id "$AGENT_SPACE_ID" --code-review-job-id "$JOBID" \
> "$WORK/findings.try.json" 2>/dev/null \
&& python3 -c 'import json,sys; sys.exit(0 if "findingsSummaries" in json.load(open(sys.argv[1])) else 1)' "$WORK/findings.try.json" 2>/dev/null; then
mv "$WORK/findings.try.json" "$WORK/findings.json"
DONE="findings"; log "findings ready (status=${STATUS}) β€” proceeding without waiting for status flip"; break
fi
sleep 20
done
if [ "$STATUS" != "COMPLETED" ] && [ "$STATUS" != "SUCCEEDED" ]; then
log "timed out waiting for review (last=${STATUS})"; post_status "error" "security: review timed out"; exit 0
if [ -z "$DONE" ]; then
# Advisory step: the App bot posts the authoritative result on the PR regardless,
# so a slow job-status flip is NOT a failure. Post a neutral pending status (not
# error) so the PR check isn't a misleading red, and continue.
log "review still running past ${POLL_TIMEOUT}s (last status=${STATUS}) β€” see the AWS Security Agent bot comment on the PR for the authoritative result"
post_status "pending" "security: review still running β€” see AWS Security Agent PR comment"
exit 0
fi

# ── 5. Fetch findings, render report + verdict (python3, no node) ────────────
aws securityagent list-findings --region "$AWS_REGION" \
--agent-space-id "$AGENT_SPACE_ID" --code-review-job-id "$JOBID" \
> "$WORK/findings.json" 2>/dev/null || echo '{"findingsSummaries":[]}' > "$WORK/findings.json"
# Reuse the findings we already fetched during the early-exit probe; only re-fetch
# if we broke on the status flip (findings not yet captured).
if [ "$DONE" = "status" ] || [ ! -s "$WORK/findings.json" ]; then
aws securityagent list-findings --region "$AWS_REGION" \
--agent-space-id "$AGENT_SPACE_ID" --code-review-job-id "$JOBID" \
> "$WORK/findings.json" 2>/dev/null || echo '{"findingsSummaries":[]}' > "$WORK/findings.json"
fi

python3 - "$WORK/findings.json" "$BLOCK_LEVEL" "$WORK/report.md" > "$WORK/verdict.env" <<'PY'
import json, sys
Expand Down