diff --git a/README.md b/README.md index 0cbde6c..a0f4c16 100644 --- a/README.md +++ b/README.md @@ -77,9 +77,10 @@ The check validates four things for every non-break-glass Agent PR: `Fixes bug-` automation token and the matching navigable `https://agenthub.fritzlab.net/bug-` URL. Every PR has a separate `## Attribution` section containing the canonical `Authored-By` - product/model watermark. The action asks Gitea to render the body and checks - the rendered `

` sections; fenced, commented, scripted, or collapsed - copies do not satisfy the visible provenance contract. + product/model watermark. The action asks Gitea to render the body with a + bounded 5-second connection and 15-second total wait, then checks visible + `

` sections outside collapsed `
` content. Fenced, commented, + scripted, or collapsed copies do not satisfy the visible provenance contract. 4. **Commit attribution** — every commit in `base-sha..head-sha`, including commits on `chore/` branches, ends with diff --git a/check.sh b/check.sh index 8c13f08..324a47a 100755 --- a/check.sh +++ b/check.sh @@ -32,16 +32,44 @@ if [ -z "${SERVER_URL}" ] || [ -z "${TOKEN}" ]; then elif ! RENDERED_BODY=$(printf '%s' "${BODY}" | jq -Rs '{Text: ., Mode: "gfm"}' | curl --fail --silent --show-error \ + --connect-timeout 5 \ + --max-time 15 \ --header "Authorization: token ${TOKEN}" \ --header "Content-Type: application/json" \ --data-binary @- "${SERVER_URL%/}/api/v1/markdown"); then echo "FAIL[check-naming]: Gitea could not render the PR body" FAILED=1 fi -if printf '%s\n' "${RENDERED_BODY}" | grep -Eiq '])'; then - echo "FAIL[check-naming]: rendered PR body must not contain collapsed details" - FAILED=1 -fi + +# A collapsed disclosure is valid supporting content, but provenance inside one +# is not visible by default. Remove details subtrees before locating sections. +VISIBLE_BODY=$(printf '%s\n' "${RENDERED_BODY}" | + awk ' + { + line=$0 "\n" + for (i=1; i<=length(line); i++) { + char=substr(line, i, 1) + if (in_tag) { + tag=tag char + if (char == ">") { + lower=tolower(tag) + if (lower ~ /^])/) details_depth++ + else if (lower ~ /^<\/details([[:space:]>])/) { + if (details_depth > 0) details_depth-- + } + else if (details_depth == 0) printf "%s", tag + in_tag=0 + tag="" + } + } + else if (char == "<") { + in_tag=1 + tag=char + } + else if (details_depth == 0) printf "%s", char + } + } + ') # ---- branch form ---- # /bug-/ @@ -81,7 +109,7 @@ if [ "${BRANCH_KIND}" = "role-bug" ]; then FAILED=1 fi - tracking=$(printf '%s\n' "${RENDERED_BODY}" | awk ' + tracking=$(printf '%s\n' "${VISIBLE_BODY}" | awk ' /]*>Tracking<\/h2>/ { in_section=1; next } /]*>/ && in_section { exit } in_section { print } @@ -90,7 +118,7 @@ if [ "${BRANCH_KIND}" = "role-bug" ]; then echo "FAIL[check-naming]: PR body must contain a non-empty ## Tracking section" FAILED=1 else - if ! printf '%s\n' "${tracking}" | grep -qE "(^|[[:space:]])Fixes[[:space:]]+${BRANCH_BUG}([^a-z0-9]|$)"; then + if ! printf '%s\n' "${tracking}" | grep -qE "(^|[[:space:]>])Fixes[[:space:]]+${BRANCH_BUG}([^a-z0-9]|$)"; then echo "FAIL[check-naming]: ## Tracking must contain the literal token 'Fixes ${BRANCH_BUG}'" FAILED=1 fi @@ -106,7 +134,7 @@ elif [ "${BRANCH_KIND}" = "chore" ] && [ -n "${TITLE_BUG}" ]; then fi if [ "${BRANCH_KIND}" != "invalid" ]; then - attribution=$(printf '%s\n' "${RENDERED_BODY}" | awk ' + attribution=$(printf '%s\n' "${VISIBLE_BODY}" | awk ' /]*>Attribution<\/h2>/ { in_section=1; next } /]*>/ && in_section { exit } in_section { print } diff --git a/tests/bin/curl b/tests/bin/curl index f7b975e..63b420a 100755 --- a/tests/bin/curl +++ b/tests/bin/curl @@ -2,6 +2,29 @@ # Deterministic Gitea Markdown renderer stub for check.sh contract tests. set -euo pipefail +connect_timeout=0 +total_timeout=0 +while [ "$#" -gt 0 ]; do + case "$1" in + --connect-timeout) + [ "${2:-}" = "5" ] || exit 2 + connect_timeout=1 + shift 2 + ;; + --max-time) + [ "${2:-}" = "15" ] || exit 2 + total_timeout=1 + shift 2 + ;; + *) shift ;; + esac +done +[ "${connect_timeout}" -eq 1 ] && [ "${total_timeout}" -eq 1 ] || exit 2 + +if printf '%s\n' "${PR_BODY}" | grep -Fq '[[stall-renderer]]'; then + exit 28 +fi + if printf '%s\n' "${PR_BODY}" | grep -Fq '