From 072560e42b701dbfeb73b27d640c0a2775063e9d Mon Sep 17 00:00:00 2001 From: kikashy <35789537+kikashy@users.noreply.github.com> Date: Fri, 30 Oct 2026 14:51:02 -0400 Subject: [PATCH] Prepare jpdev v0.13.0 JPDEV_VERSION 0.13.0, the vendored copies' line 2, and docs/releases/v0.13.0.md (#59 reported runner identity, #60 pull-request-to-branch reuse, #64 the assessment). Co-Authored-By: Claude Opus 5.5 Signed-off-by: kikashy <35789537+kikashy@users.noreply.github.com> --- docs/releases/v0.13.0.md | 59 +++++++++++++++++++++++++++++++++ lib/common.sh | 2 +- scripts/dev/changed_checks.py | 2 +- scripts/dev/check.sh | 2 +- scripts/dev/handover_check.sh | 2 +- scripts/dev/release_evidence.py | 2 +- templates/check.sh | 2 +- 7 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 docs/releases/v0.13.0.md diff --git a/docs/releases/v0.13.0.md b/docs/releases/v0.13.0.md new file mode 100644 index 0000000..08dbd42 --- /dev/null +++ b/docs/releases/v0.13.0.md @@ -0,0 +1,59 @@ +# jpdev v0.13.0 + +This release has three parts: +- The release evidence gate gains a reported runner identity for standard GitHub-hosted runners ([issue #59](https://github.com/Judgment-Pack/judgment-pack-devkit/issues/59), [pull request #66](https://github.com/Judgment-Pack/judgment-pack-devkit/pull/66)). +- An opt-in route lets a trusted branch reuse the evidence of the pull request that merged into it ([issue #60](https://github.com/Judgment-Pack/judgment-pack-devkit/issues/60), [pull request #67](https://github.com/Judgment-Pack/judgment-pack-devkit/pull/67)). +- The assessment of version-pinned CI and release infrastructure is recorded with the maintainer's decision ([pull request #64](https://github.com/Judgment-Pack/judgment-pack-devkit/pull/64)). + +## Reported runner identity + +The organization stays on standard GitHub-hosted runners. This is the maintainer's decision on #59, which takes the free-tier variant: no larger runners with custom images. The gate therefore pins what such a runner can show. This is a **reported** image identity, not a pinned VM image. The larger-runner direction stays recorded in the assessment as the route if the plan changes. + +The new manifest is `templates/runner-identity.json`, version 1, revision 1, with `identity: "reported"`. It names five variants: `linux-x64`, `linux-arm64`, `macos-arm64`, `macos-x64` and `windows-x64`. A repository opts in with an `identity: {manifest, sha256}` member in `ci-evidence.json`. Each profile then names its `variant`, a `platform.ImageOS` pin and at least one tool. + +The gate records and compares the following, always per variant and profile and never across unlike operating systems: +- `ImageOS` and `ImageVersion` as the runner reports them; +- `RUNNER_OS` and `RUNNER_ARCH`; +- the digest of the variant's OS-release file; +- the resolved tools; +- every `uses:` in the workflow, which must be pinned to a full commit or an image digest. A line that may spell the `uses` key in any other way refuses. + +There are four new refusals: +- `identity-config`: the manifest is not the shipped, pinned revision, or a profile's platform is not its variant's. +- `identity-missing`: the identity record is absent, a field is missing, or no tools are recorded. +- `identity-unexpected`: another manifest, revision, variant or set of actions; an `ImageOS` other than the pin; another operating system or architecture; an `ImageVersion` such as `latest` or a wildcard; a malformed digest; or an unpinned action. +- `identity-changed`: the legs of one profile reported different images. + +`identity-missing` and `identity-unexpected` are never revalidated. A rolled image against the release runner keeps v0.12.0's `runtime-identity` route. + +Some dependencies are admitted without being read. `docs/ci-evidence.md` lists them: +- the inner `uses:` of remote composite actions and remote reusable workflows; +- `container:` and `services:` images; +- a local Docker action's `image:`. + +## Pull-request-to-branch reuse + +A repository opts in per workflow with `workflows..pull_request_reuse: {checks, environment}`. A branch job then runs `jpdev`'s `reuse` plan before its checks, and `capture --reuse-plan` records the covered checks as `REUSED`. Tree equality alone never qualifies. The gate binds the run through records that survive the merge and that the pull request's own code cannot write: +- **One pull request.** The head branch has had exactly one pull request ever: the merged one, from this repository. +- **No base change.** That pull request's timeline shows no base-change event of any kind. Every event name containing `base_change` or `base_ref` refuses. +- **The right run.** The run is at the pull request's final head, in this repository, with event `pull_request`, and was created after the pull request was opened. +- **The merge commit.** It has this commit's first parent and the pull request head as parents, and this commit's tree. +- **Same inputs.** Inputs, tools, images and the configured environment are equal. The checks step's environment is bound through `check.sh`'s new `JPDEV_BIND_ENV` line. +- **Coverage.** Only checks configured as reusable *and* passed in that run are covered. + +The newest attempt is used whatever its result. A dispatch or a re-run never reuses. Every refusal makes the plan `fresh`, so the job runs its whole list. The refusal codes (`reuse-*`, `capture-plan`, `capture-merge`, `check-environment`) are listed in `docs/ci-evidence.md`. Without the opt-in, nothing about pull requests is read, and main-to-release reuse is unchanged. One code changed: a capture on a `pull_request` event without the opt-in now refuses `capture-event` where v0.12.0 refused `capture-ref`. + +## `check.sh` + +When `JPDEV_BIND_ENV` names variables, the template and the vendored copy print an `environment:` line in the summary block. The line holds the digest of the manifest read and of each named variable as the checks ran. Without the variable, the output is unchanged. + +## Operating limits + +- **Not live-tested.** The GitHub API reads behind the reuse binding (the head-branch listing, the timeline, the run fields) and the identity's runner variables were exercised only against fixtures modelled on read-only observations of this repository. The first live use is an adopting repository's first reuse decision, which should be watched. +- **Event names.** A future base-change event whose name contains neither `base_change` nor `base_ref` would not be refused. +- **No savings claimed.** No kit workflow adopts either feature, and nothing was timed. +- **Adoption** is each repository's own change, reviewed on its own pull request. + +## Checks run for this release + +The kit's own suites at the tagged commit: the gate's tests, `tests/run.sh` and `jpdev check --all`. Pull requests #66 and #67 had one security clean room by Claude Opus over a Claude Opus build. Two fix rounds and the same reviewer's re-read and confirmation are recorded on the pull requests. That review found a HIGH on #67, the reused run's binding, which was fixed and confirmed before merge. This is a same-vendor review, not a cross-vendor one. diff --git a/lib/common.sh b/lib/common.sh index 3d9b3e9..8c7f54b 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -3,7 +3,7 @@ # Sourced by bin/jpdev and lib/wrap.sh. Needs bash 5. # shellcheck disable=SC2034 # read by bin/jpdev -JPDEV_VERSION=0.12.0 +JPDEV_VERSION=0.13.0 # Every setting jpdev reads. The environment wins over the config file, the config file over the default. JPDEV_SETTINGS=(JPDEV_SCRATCH JPDEV_LOCK JPDEV_NODE_RSS_MB JPDEV_NODE_TIMEOUT_S JPDEV_GO_ULIMIT_KB diff --git a/scripts/dev/changed_checks.py b/scripts/dev/changed_checks.py index 4286097..7d52f61 100644 --- a/scripts/dev/changed_checks.py +++ b/scripts/dev/changed_checks.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# from judgment-pack-devkit v0.12.0 (lib/changed_checks.py) +# from judgment-pack-devkit v0.13.0 (lib/changed_checks.py) """changed_checks.py --root ROOT --manifest MANIFEST [--base BASE] [--label TEXT] Selects the check-list steps that the changed paths of a clone can affect, for diff --git a/scripts/dev/check.sh b/scripts/dev/check.sh index 761c121..34e43c3 100755 --- a/scripts/dev/check.sh +++ b/scripts/dev/check.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# from judgment-pack-devkit v0.12.0 (templates/check.sh) +# from judgment-pack-devkit v0.13.0 (templates/check.sh) # scripts/dev/check.sh [--setup] [--only a,b | --changed [BASE]] [--skip a,b] [--all] [--strict] [--manifest FILE] # Runs dev.json checks in order; exit counts failures, or is nonzero for infrastructure-unrun checks. # --changed runs only the checks jpdev.json maps the paths changed since the merge base of BASE diff --git a/scripts/dev/handover_check.sh b/scripts/dev/handover_check.sh index 64311c8..75ba264 100755 --- a/scripts/dev/handover_check.sh +++ b/scripts/dev/handover_check.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# from judgment-pack-devkit v0.12.0 (lib/handover_check.sh) +# from judgment-pack-devkit v0.13.0 (lib/handover_check.sh) set -eu python3 - <<'PY' diff --git a/scripts/dev/release_evidence.py b/scripts/dev/release_evidence.py index 63d1a20..bd8a2c8 100644 --- a/scripts/dev/release_evidence.py +++ b/scripts/dev/release_evidence.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# from judgment-pack-devkit v0.12.0 (lib/release_evidence.py) +# from judgment-pack-devkit v0.13.0 (lib/release_evidence.py) """release_evidence.py capture|verify|reuse: reuse the CI evidence main produced at the release commit. capture Runs in a CI job on the trusted branch, after the job's checks. Writes evidence.json for diff --git a/templates/check.sh b/templates/check.sh index 761c121..34e43c3 100755 --- a/templates/check.sh +++ b/templates/check.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# from judgment-pack-devkit v0.12.0 (templates/check.sh) +# from judgment-pack-devkit v0.13.0 (templates/check.sh) # scripts/dev/check.sh [--setup] [--only a,b | --changed [BASE]] [--skip a,b] [--all] [--strict] [--manifest FILE] # Runs dev.json checks in order; exit counts failures, or is nonzero for infrastructure-unrun checks. # --changed runs only the checks jpdev.json maps the paths changed since the merge base of BASE