fix: preserve child stderr and attach diagnostic codes - #9
Conversation
Child process failures named the stage but dropped stderr, so operators could not see why decide/act/prove actually failed. Clip and record stderr on stage errors, tag spawn/exit/JSON problems with AAS_CHILD_* codes, and print those diagnostics on the human and JSON error paths.
There was a problem hiding this comment.
Devin Review found 2 potential issues.
1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)
| const missing = new Error(`Python not found for decide stage${lastError ? ` (${lastError.code ?? "spawn-error"})` : ""}`); | ||
| throw attachChildDiagnostics(missing, { | ||
| stage: "decide", | ||
| code: DIAGNOSTIC.CHILD_SPAWN, | ||
| stderr: lastError?.message, |
There was a problem hiding this comment.
🟡 Decide spawn failures lose stderr
When every Python attempt returns a spawn error with captured output, runDecide keeps only the Error object. The recorded diagnostic substitutes Node’s message for the child’s stderr.
Prompt for agents
In bin/aas.mjs, runDecide discards each ChildResult when result.error is present and retains only result.error. spawnSync can return both an error and captured stderr, such as when maxBuffer is exceeded. Track the last failed ChildResult, then attach its stderr to the final AAS_CHILD_SPAWN error while continuing to use the underlying error code in the reason. Add a test where every Python candidate returns both error and stderr and verify the stage report and manifest preserve the child stderr.
Was this helpful? React with 👍 or 👎 to provide feedback.
| function failedStderr(result) { | ||
| const stderr = clipChildStderr(result?.stderr); | ||
| return stderr ? { stderr } : {}; |
There was a problem hiding this comment.
🟨 Child stderr can expose secrets
When a dependency prints credentials in stderr, failedStderr copies them into reports, manifests, GUI responses, downloads, and terminal output. Clipping and control-character removal provide no secret redaction.
Was this helpful? React with 👍 or 👎 to provide feedback.
What
Child process failures from decide/act/prove now keep a clipped copy of stderr and a diagnostic code (
AAS_CHILD_SPAWN,AAS_CHILD_EXIT,AAS_CHILD_JSON).codeandstderron failed/error stages.*_code,*_reason, and*_stderronly on failed/error paths (pass-path README sample is unchanged).code,stage, andstderrwhen present.Why
runCapturealready collected stderr, then threw it away. Operators only sawprove child process exited with status 2with no child diagnostic. This cycle’s theme is logging, diagnostics, and failure messages.How tested
npm test(35 passing)node --checkonbin/aas.mjs,bin/aas-gui.mjs, andscripts/bootstrap.mjs