feat(opencode): the OpenCode harness, checked against its goldens
The tool source generated from the schema, the home with its view, the shared and per-process environments, the permission rules, the commands, the warm-up under the supervisor, the event stream and the classification, its patterns as hand-written scanners. The goldens record the answer for each, a warm-up against a fake opencode included. A timed-out supervised command now gets SIGTERM, so the supervisor takes its tree down (SIGKILL 10 s later); any other child gets SIGKILL. :Json gains DumpCompact. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
c63c898833
commit
5253fe3aff
10 changed files with 1946 additions and 7 deletions
|
|
@ -324,7 +324,9 @@ namespace Crafter::Review::Process {
|
|||
if (deadline) {
|
||||
const auto left = std::chrono::duration_cast<std::chrono::milliseconds>(*deadline - std::chrono::steady_clock::now()).count();
|
||||
if (left <= 0) {
|
||||
Signal(child.pid, SIGKILL);
|
||||
// A supervisor takes the whole tree down on SIGTERM; any
|
||||
// other child gets SIGKILL.
|
||||
Signal(child.pid, argv.size() > 1 && argv[1] == SuperviseVerb ? SIGTERM : SIGKILL);
|
||||
captured.timedOut = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -360,7 +362,12 @@ namespace Crafter::Review::Process {
|
|||
for (const std::int32_t fd : { child.input, child.output, child.error }) {
|
||||
if (fd >= 0) close(fd);
|
||||
}
|
||||
captured.returnCode = Wait(child.pid).value_or(-1);
|
||||
std::optional<std::int32_t> code = Wait(child.pid, captured.timedOut ? std::optional(std::chrono::milliseconds(10000)) : std::nullopt);
|
||||
if (!code) {
|
||||
Signal(child.pid, SIGKILL);
|
||||
code = Wait(child.pid);
|
||||
}
|
||||
captured.returnCode = code.value_or(-1);
|
||||
return captured;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue