You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2026/05/17 05:26:18 UTC

(groovy) branch master updated (1c20a0f307 -> 7f4fb8afd4)

This is an automated email from the ASF dual-hosted git repository.

paulk-asert pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


    from 1c20a0f307 AI readiness: backport changes from magpie learnings
     new dec7cf5a77 AI readiness: backport changes from magpie learnings
     new 7f4fb8afd4 AI readiness: sandboxed reproducers

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .agents/skills/groovy-reproducer/SKILL.md          |  22 +++-
 .../groovy-reproducer/run-reproducer-sandboxed.sh  | 143 +++++++++++++++++++++
 versions.properties                                |   1 +
 3 files changed, 164 insertions(+), 2 deletions(-)
 create mode 100755 .agents/skills/groovy-reproducer/run-reproducer-sandboxed.sh


(groovy) 01/02: AI readiness: backport changes from magpie learnings

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk-asert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit dec7cf5a77141ac102a97b54ccfee25c6cbc7831
Author: Paul King <pa...@asert.com.au>
AuthorDate: Sun May 17 15:00:53 2026 +1000

    AI readiness: backport changes from magpie learnings
---
 versions.properties | 1 +
 1 file changed, 1 insertion(+)

diff --git a/versions.properties b/versions.properties
index cd7356299f..82fb462998 100644
--- a/versions.properties
+++ b/versions.properties
@@ -51,6 +51,7 @@ junit6=6.0.3
 latest3=3.0.25
 latest4=4.0.32
 latest5=5.0.6
+latest6=6.0.0-alpha-1
 javaxInject=1
 log4j=1.2.17
 log4j2=2.26.0


(groovy) 02/02: AI readiness: sandboxed reproducers

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk-asert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 7f4fb8afd4c72bb5da84bb74fc9181c607f4dce8
Author: Paul King <pa...@asert.com.au>
AuthorDate: Sun May 17 15:26:09 2026 +1000

    AI readiness: sandboxed reproducers
---
 .agents/skills/groovy-reproducer/SKILL.md          |  22 +++-
 .../groovy-reproducer/run-reproducer-sandboxed.sh  | 143 +++++++++++++++++++++
 2 files changed, 163 insertions(+), 2 deletions(-)

diff --git a/.agents/skills/groovy-reproducer/SKILL.md b/.agents/skills/groovy-reproducer/SKILL.md
index fb5c235a03..1ebfde651b 100644
--- a/.agents/skills/groovy-reproducer/SKILL.md
+++ b/.agents/skills/groovy-reproducer/SKILL.md
@@ -404,8 +404,20 @@ For each reproducer:
    triage of the issue and always goes through this gate. This
    is a project-wide rule — see
    [`AGENTS.md`](../../../AGENTS.md#untrusted-input-and-confirmation).
-   A sandboxed run (container/VM) is the escalation for a
-   flagged or uneasy case, not a routine requirement.
+   A sandboxed run is the escalation for a flagged or uneasy
+   case, not a routine requirement: the *run-sandboxed* choice
+   invokes [`run-reproducer-sandboxed.sh`](run-reproducer-sandboxed.sh)
+   `--line {3|4|5} <file>` — a locked-down Docker run against the
+   pinned latest released Groovy of that line (the community
+   Docker Official `groovy` image, jdk21 variant; Apache Groovy
+   publishes no images of its own). There is no `6` line — the
+   project publishes no 6.x alpha/beta images, so 6.x/`master`
+   (`6.0.0-SNAPSHOT`) is the separate local-build path (Option B)
+   and a `fixed-on-master` verdict is **never** claimed from a
+   released-line sandbox run. It is blast-radius reduction, not a
+   jail. Record the resolved version + sha256 the script prints
+   into `verdict.json` (`rev` = the concrete version, never the
+   moving "latest" label; `safety_review.isolation = sandbox`).
 7. **Run with bounded resources.** Timeout (60s default), capture
    stdout + stderr + exit code + runtime. Record the command
    verbatim. Run with **`-Dgroovy.grape.enable=false` by
@@ -674,6 +686,12 @@ Before recording a verdict:
   pre-screen the step-6 gate runs over the adapted reproducer; a
   shipped helper (per the AGENTS token-economy policy), explicitly
   shallow and not a substitute for the human review.
+- [`run-reproducer-sandboxed.sh`](run-reproducer-sandboxed.sh) —
+  the step-6 *run-sandboxed* escalation: a hardened, ephemeral
+  Docker run against the pinned latest released Groovy of line
+  3/4/5 (community Docker Official `groovy` image, jdk21).
+  Blast-radius reduction, not a jail; no 6.x line; does not
+  cover the `master` build (Option B).
 - `.agents/skills/groovy-triage/SKILL.md` — single-issue caller;
   AI guardrails over the triage methodology in
   [`CONTRIBUTING.md`](../../../CONTRIBUTING.md#triaging-issues-and-pull-requests).
diff --git a/.agents/skills/groovy-reproducer/run-reproducer-sandboxed.sh b/.agents/skills/groovy-reproducer/run-reproducer-sandboxed.sh
new file mode 100755
index 0000000000..6281708d16
--- /dev/null
+++ b/.agents/skills/groovy-reproducer/run-reproducer-sandboxed.sh
@@ -0,0 +1,143 @@
+#!/usr/bin/env bash
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+# run-reproducer-sandboxed.sh — run ONE script / self-contained @Test
+# reproducer inside a locked-down Docker container against a *pinned
+# released* Groovy (Option A). Invoked by the step-6 safety gate in
+# SKILL.md when the human chooses "run-sandboxed".
+#
+# This is BLAST-RADIUS REDUCTION, not a jail. Container escape exists
+# (shared kernel; the Docker daemon is host-root-equivalent). It sits
+# *behind* the pre-screen + human gate, never instead of them. It does
+# NOT cover: the current master build (that is Option B — a different
+# path), @Grab/network (network is disabled), seccomp/AppArmor beyond
+# Docker defaults, rootless Docker, or multi-file/project reproducers.
+#
+# The `docker run` below IS the documented manual equivalent (per
+# AGENTS.md "Helper mechanisms and token economy"): run it by hand if
+# you need to adapt it.
+#
+# Usage:
+#   run-reproducer-sandboxed.sh --line {3|4|5} <reproducer-file> [--timeout S]
+#   run-reproducer-sandboxed.sh --image <ref>  <reproducer-file> [--timeout S]
+#
+#   --line N     latest *released* Groovy of major line N (3|4|5),
+#                resolved via the pin table below. There is no 6.x
+#                entry: the community Docker Official images do not
+#                publish 6.x alpha/beta; testing 6.x / master
+#                (6.0.0-SNAPSHOT) is the separate local-build path
+#                (Option B), which this script refuses.
+#   --image REF  explicit image ref/digest, bypassing the table.
+#
+# Records, on stderr, the concrete image AND its sha256 digest so the
+# caller can stamp verdict.json (`rev` = the resolved Groovy version,
+# never the moving "latest" label; `safety_review.isolation` = sandbox).
+set -euo pipefail
+
+# ---------------------------------------------------------------------------
+# Image pin table.
+#
+# Source: the Docker Official `groovy` image (https://hub.docker.com/_/groovy),
+# built by the community project https://github.com/groovy/docker-groovy.
+# Apache Groovy does NOT publish any images under apache/groovy. The
+# jdk21 variant is used for all lines (per the docker-groovy
+# groovy-N/jdk21/Dockerfile layout). There is deliberately no 6.x line:
+# the project does not publish alpha/beta images; 6.x/master is Option B.
+#
+# Tags are mutable — these pin the *current* latest patch per line; the
+# run resolves and records the immutable sha256 (RESOLVED_DIGEST) so the
+# verdict is reproducible regardless. Bump these as new patch releases
+# publish (a deliberate, reviewed edit — do not auto-track "latest").
+# Override per-run with --image <ref> for a specific patch/JDK/digest.
+# ---------------------------------------------------------------------------
+RATIFIED_IMAGE_3='groovy:3.0.25-jdk21'
+RATIFIED_IMAGE_4='groovy:4.0.32-jdk21'
+RATIFIED_IMAGE_5='groovy:5.0.6-jdk21'
+
+TIMEOUT=60
+LINE=''
+IMAGE=''
+FILE=''
+
+die() { echo "run-reproducer-sandboxed: $*" >&2; exit 2; }
+
+while [[ $# -gt 0 ]]; do
+  case "$1" in
+    --line)    LINE="${2:?--line needs a value}"; shift 2 ;;
+    --image)   IMAGE="${2:?--image needs a value}"; shift 2 ;;
+    --timeout) TIMEOUT="${2:?--timeout needs a value}"; shift 2 ;;
+    -h|--help) awk '/^# run-reproducer-sandboxed\.sh/,/^set -euo pipefail/' "$0" | grep '^#' | sed 's/^# \{0,1\}//'; exit 0 ;;
+    -*)        die "unknown option: $1" ;;
+    *)         FILE="$1"; shift ;;
+  esac
+done
+
+[[ -n "$FILE" ]]      || die "no reproducer file given (see --help)"
+[[ -r "$FILE" ]]      || die "cannot read reproducer file: $FILE"
+command -v docker >/dev/null 2>&1 || die "docker not found on PATH — this is the Option-A sandbox path and requires Docker"
+
+# Reject master / SNAPSHOT here — that is Option B (mounted fresh build),
+# a different path. Never silently substitute (no-silent-fallback rule).
+# Reject master / SNAPSHOT / 6.x here — there is no released community
+# image for those; that is Option B (mounted fresh build), a different
+# path. Never silently substitute (no-silent-fallback rule).
+case "${LINE}" in
+  m|master|snapshot|SNAPSHOT) die "--line '$LINE' is the master build (Option B), not this script. Run the local-build path instead." ;;
+  6) die "no community-published release image for Groovy 6.x (no alpha/beta images on hub.docker.com/_/groovy). Test 6.x/master via the local-build path (Option B)." ;;
+esac
+
+if [[ -z "$IMAGE" ]]; then
+  [[ -n "$LINE" ]] || die "need --line {3|4|5} or --image <ref>"
+  case "$LINE" in
+    3) IMAGE="$RATIFIED_IMAGE_3" ;;
+    4) IMAGE="$RATIFIED_IMAGE_4" ;;
+    5) IMAGE="$RATIFIED_IMAGE_5" ;;
+    *) die "--line must be one of 3 4 5 (got '$LINE')" ;;
+  esac
+fi
+
+# Fail fast if the image does not exist / is unreachable (Docker images
+# lag releases; surface that, do not substitute another line).
+echo "run-reproducer-sandboxed: pulling ${IMAGE} ..." >&2
+docker pull "$IMAGE" >&2 || die "image not available: ${IMAGE} (Docker publish often lags a release; do not substitute another version — escalate to Option B or an explicit --image)"
+
+DIGEST="$(docker image inspect --format '{{ if .RepoDigests }}{{ index .RepoDigests 0 }}{{ end }}' "$IMAGE" 2>/dev/null || true)"
+echo "RESOLVED_IMAGE=${IMAGE}" >&2
+echo "RESOLVED_DIGEST=${DIGEST:-<none>}" >&2
+
+SCRATCH="$(cd "$(dirname "$FILE")" && pwd)"
+BASE="$(basename "$FILE")"
+
+# Hardened, ephemeral. Load-bearing: --network none (no exfil/pull),
+# --read-only + tmpfs (no persistence), only the throwaway scratch dir
+# mounted rw, no $HOME, no docker socket. The rest are one-flag wins.
+set -x
+timeout "${TIMEOUT}" docker run --rm \
+  --network none \
+  --read-only --tmpfs /tmp \
+  --env HOME=/tmp \
+  --volume "${SCRATCH}:/work:rw" \
+  --workdir /work \
+  --cap-drop=ALL --security-opt=no-new-privileges \
+  --pids-limit=256 --memory=1g --memory-swap=1g --cpus=2 \
+  "$IMAGE" \
+  groovy "/work/${BASE}"
+rc=$?
+set +x
+exit $rc