Skip to content

fix: runAct treats nonzero-exit JSON as a failed act, like runDecide and runProve - #13

Merged
EauDoon merged 1 commit into
mainfrom
fix/runact-treat-nonzero-json-as-failed-act
Sep 4, 2026
Merged

fix: runAct treats nonzero-exit JSON as a failed act, like runDecide and runProve#13
EauDoon merged 1 commit into
mainfrom
fix/runact-treat-nonzero-json-as-failed-act

Conversation

@EauDoon

@EauDoon EauDoon commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Bug review of EauDoon/agent-action-stack found:

  • MEDIUM: runAct (bin/aas.mjs) short-circuits to childProcessError when result.status !== 0, before parseStageJson is reached. Any JSON crctl wrote to stdout is dropped. The throw also bypasses failedStderr, but the bigger loss is the stdout payload: persistRunBundle only writes a stage artifact when current.raw !== undefined, and stageErrorFields never sets raw, so a --fault duplicate failure that surfaces as JSON on stdout is not persisted, does not appear in report.stages.act, and printHuman shows only act_code / act_reason / act_stderr. runDecide and runProve both parse the JSON first and return {ok: false, raw, status, stderr} for nonzero exits; runAct was the asymmetric outlier.

Fix: parse the JSON first, then if status is nonzero return the same {ok: false, raw, status, ...failedStderr(result)} shape that runDecide and runProve use. Throw childProcessError only when the spawn itself failed (result.error) or when the child exited nonzero with no parseable JSON.

Verified: node --test test/stack.test.mjs runs 40 tests, all pass.


Devin Review

…and runProve

Bug review of EauDoon/agent-action-stack found:
- MEDIUM: runAct (bin/aas.mjs) short-circuits to childProcessError when result.status !== 0, before parseStageJson is reached. Any JSON crctl wrote to stdout is dropped. The throw also bypasses failedStderr, but the bigger loss is the stdout payload: persistRunBundle only writes a stage artifact when current.raw !== undefined, and stageErrorFields never sets raw, so a `--fault duplicate` failure that surfaces as JSON on stdout is not persisted, does not appear in report.stages.act, and printHuman shows only act_code / act_reason / act_stderr. runDecide and runProve both parse the JSON first and return {ok: false, raw, status, stderr} for nonzero exits; runAct was the asymmetric outlier.

Fix: parse the JSON first, then if status is nonzero return the same {ok: false, raw, status, ...failedStderr(result)} shape that runDecide and runProve use. Throw childProcessError only when the spawn itself failed (result.error) or when the child exited nonzero with no parseable JSON.

Verified: node --test test/stack.test.mjs runs 40 tests, all pass.
@EauDoon
EauDoon merged commit f5dc37c into main Sep 4, 2026
@EauDoon
EauDoon deleted the fix/runact-treat-nonzero-json-as-failed-act branch September 4, 2026 10:33

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

Devin Review

Comment thread bin/aas.mjs
Comment on lines +525 to +530
if (result.status !== 0) {
// A nonzero exit with parseable JSON is an unsuccessful act (the CLI
// surfaces structured errors as JSON on stdout), not a child-process
// error. Mirror runProve so persistRunBundle and printHuman see the
// structured failure and the GUI can render the stage artifact.
return { ok: false, raw: payload, status: result.status, ...failedStderr(result) };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Failed actions still report success

When runAct returns ok: false, the demo marks the action passed and never raises its exit code. A successful proof then reports the failed action as a successful run.

Prompt for agents
Update the act handling in bin/aas.mjs runDemo to consume runAct's new ok/status contract. A result with ok: false must record the act stage as failed, preserve raw and stderr for the bundle and report, set the overall exit code to failure, and avoid presenting the action as passed. Define whether proof still runs for failed actions based on the structured outcome, while ensuring a successful proof cannot erase the action failure. Add coverage for nonzero act JSON through runDemo, including the persisted artifact, stage status, and process exit code.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant