Skip to content

feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs - #1138

Merged
hyperpolymath merged 1 commit into
mainfrom
feat/uuid-v7-julia-dependency-tables
Oct 2, 2026
Merged

hyperpolymath merged 1 commit into
mainfrom
feat/uuid-v7-julia-dependency-tables

Conversation

@hyperpolymath

@hyperpolymath hyperpolymath commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Governance change: it needs review by both estate owners. Per docs/UUID-V7-ESTATE-STANDARD.adoc, narrowing what the UUID v7 gate scans counts as weakening it, so this PR must not be auto-merged.

Why

Julia names every dependency by the UUID the General registry assigned it, and a dependant cannot change that UUID. Today, therefore, no Julia repository can pass check-uuid-v7.sh. Measured on hyperpolymath/ZenodoDeposits.jl: 14 findings, of which 12 are in Project.toml. The standard already says external identifiers are "preserve and type explicitly". A Julia dependency table is exactly that kind of typed context.

What changes

  • scripts/check-uuid-v7.sh:
    • New function scannable_text.
    • In Project.toml and JuliaProject.toml, the [deps], [weakdeps] and [extras] tables are not scanned. A package's own top-level uuid = is still checked.
    • Manifest*.toml and JuliaManifest*.toml are not scanned. Every entry in them is a resolved dependency.
    • The text scanned is a strict subset of what was scanned before, so nothing that passed now fails.
  • scripts/tests/uuid-v7-test.sh: five new cases, all with UUIDs assembled at runtime as before. 16/16 pass.
  • docs/UUID-V7-ESTATE-STANDARD.adoc: revised to v1.1. It now describes the exemption, assesses the migration impact, and says new Julia packages must mint their own UUID as v7 before registration.

.machine_readable/uuid-v7-estate-standard.a2ml (version "1.0.0") is deliberately not touched, under the estate A2ML doctrine. Its version string now trails the adoc.

Evidence

  • bash scripts/tests/uuid-v7-test.sh passes 16/16, rc 0.
  • Mutant 1 (the checker from main): exactly the two acceptance cases fail, the [deps] case and the Manifest case.
  • Mutant 2 (the whole of Project.toml exempted): exactly the two narrowness cases fail, the own-uuid case and the "exemption ends at the next table" case.
  • sh scripts/check-uuid-v7.sh . on this repo gives rc 0. The docstring scan reports 100%.

Owner decision 2026-10-02: exempt dependency tables only. Needed by metadatastician/ZenodoDeposits.jl#3, along with a v7 re-mint of that package's own UUID before registration.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JPmNukJT5PUzQ9d74mhHhj

Deferred red check (§5c)

Julia names every dependency by the UUID the General registry assigned it,
so a Julia repository cannot pass check-uuid-v7.sh however it is written.
The standard already says external identifiers are preserved and typed
explicitly; Project.toml dependency tables are such a typed context.

The checker now skips the [deps], [weakdeps] and [extras] tables of
Project.toml / JuliaProject.toml, and Julia Manifests. A package's own
top-level `uuid =` is still checked, so new Julia packages mint v7 before
registration. Scanned text is a subset of before: nothing that passed fails.

Five new cases in uuid-v7-test.sh (16/16 pass). Mutants: the main checker
fails exactly the two acceptance cases; a whole-file Project.toml exemption
fails exactly the two narrowness cases. Standard revised to v1.1.

Owner decision 2026-10-02 (selection UI): dependency tables only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JPmNukJT5PUzQ9d74mhHhj
@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 90a822ca-1a4a-4705-9b99-0e92ba37a5dc

📥 Commits

Reviewing files that changed from the base of the PR and between e2e0f6d and 67e991e.

📒 Files selected for processing (3)
  • docs/UUID-V7-ESTATE-STANDARD.adoc
  • scripts/check-uuid-v7.sh
  • scripts/tests/uuid-v7-test.sh

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (24)
  • GitHub Check: Trust pipeline summary
  • GitHub Check: analyze-actions / analyze
  • GitHub Check: analyze-js / analyze
  • GitHub Check: governance / Licence consistency
  • GitHub Check: governance / UUID v7 conformance
  • GitHub Check: scan / Hypatia Neurosymbolic Analysis
  • GitHub Check: governance / Actions lockfile verify
  • GitHub Check: governance / Debt ratchet
  • GitHub Check: governance / Guix packaging policy (Nix retired)
  • GitHub Check: governance / Workflow security linter
  • GitHub Check: governance / Exemption ratchet
  • GitHub Check: governance / Code quality + docs
  • GitHub Check: governance / Language / package anti-pattern policy
  • GitHub Check: governance / Allowlist Preflight
  • GitHub Check: governance / Check Workflow Staleness
  • GitHub Check: scorecard / Run Scorecard PR
  • GitHub Check: Repo self-tests
  • GitHub Check: scan / gitleaks
  • GitHub Check: uses ⊆ actions.lock
  • GitHub Check: K9-SVC contractile validation
  • GitHub Check: Registry + topology in sync
  • GitHub Check: Lockfile self-consistency
  • GitHub Check: GitGuardian Security Checks
  • GitHub Check: semgrep-cloud-platform/scan
⚠️ CI failures not shown inline (15)

GitHub Actions: Governance / 0_governance _ Validate Hypatia Baseline.txt: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run set -euo pipefail
 �[36;1mset -euo pipefail�[0m
 �[36;1mif [ ! -d "$HOME/hypatia" ]; then�[0m
 �[36;1m  git init "$HOME/hypatia"�[0m
 �[36;1m  git -C "$HOME/hypatia" remote add origin https://github.com/hyperpolymath/hypatia.git�[0m
 �[36;1m  git -C "$HOME/hypatia" fetch --depth 1 origin "$HYPATIA_SHA"�[0m
 �[36;1m  git -C "$HOME/hypatia" checkout --detach FETCH_HEAD�[0m
 �[36;1mfi�[0m
 �[36;1mACTUAL_SHA=$(git -C "$HOME/hypatia" rev-parse HEAD)�[0m
 �[36;1mif [ "$ACTUAL_SHA" != "$HYPATIA_SHA" ]; then�[0m
 �[36;1m  echo "::error::Hypatia cached source does not match the resolved commit"�[0m

GitHub Actions: Governance / governance _ Validate Hypatia Baseline: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run set -euo pipefail
 �[36;1mset -euo pipefail�[0m
 �[36;1mif [ ! -d "$HOME/hypatia" ]; then�[0m
 �[36;1m  git init "$HOME/hypatia"�[0m
 �[36;1m  git -C "$HOME/hypatia" remote add origin https://github.com/hyperpolymath/hypatia.git�[0m
 �[36;1m  git -C "$HOME/hypatia" fetch --depth 1 origin "$HYPATIA_SHA"�[0m
 �[36;1m  git -C "$HOME/hypatia" checkout --detach FETCH_HEAD�[0m
 �[36;1mfi�[0m
 �[36;1mACTUAL_SHA=$(git -C "$HOME/hypatia" rev-parse HEAD)�[0m
 �[36;1mif [ "$ACTUAL_SHA" != "$HYPATIA_SHA" ]; then�[0m
 �[36;1m  echo "::error::Hypatia cached source does not match the resolved commit"�[0m

GitHub Actions: Governance / governance _ Validate Hypatia Baseline: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run cd "$HOME/hypatia"
 �[36;1mcd "$HOME/hypatia"�[0m
 �[36;1mif [ ! -x hypatia ]; then�[0m
 �[36;1m  if ! (mix deps.get && mix escript.build); then�[0m
 �[36;1m    echo "::error::Hypatia scanner build failed at commit $(git rev-parse HEAD) — see upstream hyperpolymath/hypatia"�[0m

GitHub Actions: Governance / governance _ Validate Hypatia Baseline: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run echo "Scanning repository: hyperpolymath/standards (checking baseline)"
 �[36;1mecho "Scanning repository: hyperpolymath/standards (checking baseline)"�[0m
 �[36;1m# Move the baseline filter OUT of the scanned tree, then delete the�[0m
 �[36;1m# standards checkout, so `hypatia scan .` only ever sees the CALLER's�[0m
 �[36;1m# own files. Without this, `.standards-checkout/` (the tooling we�[0m
 �[36;1m# checked out to get apply-baseline.sh) is itself scanned, and�[0m
 �[36;1m# standards' own files get reported as the caller's findings (a banned�[0m
 �[36;1m# `.ts`, `shell_download` bootstrap.sh scripts, etc.).�[0m
 �[36;1m# Prefer the CALLER's own scripts/apply-baseline.sh when present�[0m
 �[36;1m# (self-lint: standards validating itself must run the tree under�[0m
 �[36;1m# test, not main's copy — a new baseline severity the main-pinned�[0m
 �[36;1m# script doesn't know would fail closed here while passing�[0m
 �[36;1m# everywhere else). Consumers without the script keep the�[0m
 �[36;1m# main-pinned fallback.�[0m
 �[36;1mif [ -f scripts/apply-baseline.sh ]; then�[0m
 �[36;1m  cp scripts/apply-baseline.sh "$RUNNER_TEMP/apply-baseline.sh"�[0m
 �[36;1melse�[0m
 �[36;1m  cp .standards-checkout/scripts/apply-baseline.sh "$RUNNER_TEMP/apply-baseline.sh"�[0m
 �[36;1mfi�[0m
 �[36;1mrm -rf .standards-checkout�[0m
 �[36;1m# hypatia's `scan` exits non-zero whenever it finds anything — that is�[0m
 �[36;1m# by design, and under `bash -e` it would abort this step at this line,�[0m
 �[36;1m# before the baseline filter (the real gate) ever runs. Tolerate the�[0m
 �[36;1m# scan's own exit code…�[0m
 �[36;1mHYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . > hypatia-findings.raw.json || true�[0m
 �[36;1m# …but never swallow a genuine scanner crash into a false pass: require a�[0m
 �[36;1m# valid JSON array before trusting the output as "the findings".�[0m
 �[36;1mif ! jq -e 'type == "array"' hypatia-findings.raw.json >/dev/null 2>&1; then�[0m
 �[36;1m  echo...

GitHub Actions: Governance / 1_governance _ Actions lockfile verify.txt: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1m# Stage the gate, the verifier and the exemption ledger. When THIS�[0m
 �[36;1m# repository is standards, its own working tree already holds all�[0m
 �[36;1m# three (self-lint); every other caller uses the pinned checkout.�[0m
 �[36;1mif [ "$GITHUB_REPOSITORY" = hyperpolymath/standards ]; then�[0m
 �[36;1m  SRC=scripts�[0m
 �[36;1m  LEDGERSRC=.machine_readable�[0m
 �[36;1m  echo "Using this repository's own gate + verifier + ledger (standards self-lint)."�[0m
 �[36;1melse�[0m
 �[36;1m  SRC=.standards-lock/scripts�[0m
 �[36;1m  LEDGERSRC=.standards-lock/.machine_readable�[0m
 �[36;1mfi�[0m
 �[36;1mfor f in check-actions-lock-gate.sh update-actions-lock.sh; do�[0m
 �[36;1m  if [ ! -f "$SRC/$f" ]; then�[0m
 �[36;1m    echo "::error::actions-lock gate: $f not found in $SRC (pinned standards checkout failed?)"�[0m

GitHub Actions: Governance / governance _ Actions lockfile verify: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1m# Stage the gate, the verifier and the exemption ledger. When THIS�[0m
 �[36;1m# repository is standards, its own working tree already holds all�[0m
 �[36;1m# three (self-lint); every other caller uses the pinned checkout.�[0m
 �[36;1mif [ "$GITHUB_REPOSITORY" = hyperpolymath/standards ]; then�[0m
 �[36;1m  SRC=scripts�[0m
 �[36;1m  LEDGERSRC=.machine_readable�[0m
 �[36;1m  echo "Using this repository's own gate + verifier + ledger (standards self-lint)."�[0m
 �[36;1melse�[0m
 �[36;1m  SRC=.standards-lock/scripts�[0m
 �[36;1m  LEDGERSRC=.standards-lock/.machine_readable�[0m
 �[36;1mfi�[0m
 �[36;1mfor f in check-actions-lock-gate.sh update-actions-lock.sh; do�[0m
 �[36;1m  if [ ! -f "$SRC/$f" ]; then�[0m
 �[36;1m    echo "::error::actions-lock gate: $f not found in $SRC (pinned standards checkout failed?)"�[0m

GitHub Actions: Governance / 2_governance _ Well-Known (RFC 9116 + RSR).txt: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run SECTXT=""
 �[36;1mSECTXT=""�[0m
 �[36;1m[ -f ".well-known/security.txt" ] && SECTXT=".well-known/security.txt"�[0m
 �[36;1m[ -f "security.txt" ] && SECTXT="security.txt"�[0m
 �[36;1mif [ -z "$SECTXT" ]; then�[0m
 �[36;1m  echo "::warning::No security.txt found."�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mgrep -q "^Contact:" "$SECTXT" || { echo "::error::Missing Contact field"; exit 1; }�[0m

GitHub Actions: Governance / governance _ Well-Known (RFC 9116 + RSR): feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run SECTXT=""
 �[36;1mSECTXT=""�[0m
 �[36;1m[ -f ".well-known/security.txt" ] && SECTXT=".well-known/security.txt"�[0m
 �[36;1m[ -f "security.txt" ] && SECTXT="security.txt"�[0m
 �[36;1mif [ -z "$SECTXT" ]; then�[0m
 �[36;1m  echo "::warning::No security.txt found."�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1mgrep -q "^Contact:" "$SECTXT" || { echo "::error::Missing Contact field"; exit 1; }�[0m

GitHub Actions: Governance / governance _ Well-Known (RFC 9116 + RSR): feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run MIXED=$(grep -rE 'src="http://|href="http://' --include="*.html" --include="*.htm" . 2>/dev/null | grep -vE 'localhost|127\.0\.0\.1|example\.com|lol/|node_modules/|third-party/|vendor/' | head -5)
 �[36;1mMIXED=$(grep -rE 'src="http://|href="http://' --include="*.html" --include="*.htm" . 2>/dev/null | grep -vE 'localhost|127\.0\.0\.1|example\.com|lol/|node_modules/|third-party/|vendor/' | head -5)�[0m
 �[36;1mif [ -n "$MIXED" ]; then�[0m
 �[36;1m  echo "::error::Mixed content (HTTP in HTML)"�[0m

GitHub Actions: Governance / 3_governance _ Security policy checks.txt: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1mDIR=.github/canonical-references�[0m
 �[36;1mif [ ! -d "$DIR" ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] no $DIR/ — skipped (repo has not opted in)"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1m# Rule files are read with yq, never a hand parser (YAML-POLICY Y-1); this�[0m
 �[36;1m# gate previously parsed them with Python, which the estate bans.�[0m
 �[36;1mif ! command -v yq >/dev/null 2>&1 || ! command -v jq >/dev/null 2>&1; then�[0m
 �[36;1m  echo "❌ [R5] yq and jq are required on the runner for YAML rule parsing"�[0m
 �[36;1m  exit 2�[0m
 �[36;1mfi�[0m
 �[36;1mmapfile -t files < <(find "$DIR" -maxdepth 1 -type f \( -name '*.yml' -o -name '*.yaml' \) ! -name '.*' | LC_ALL=C sort)�[0m
 �[36;1mif [ "${#files[@]}" -eq 0 ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] $DIR/ has no .yml/.yaml rules — skipped"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1m�[0m
 �[36;1merr=$(mktemp)�[0m
 �[36;1mtrap 'rm -f "$err"' EXIT�[0m
 �[36;1mtotal=0�[0m
 �[36;1mfor rf in "${files[@]}"; do�[0m
 �[36;1m  if ! cfg=$(yq -o json '.' "$rf" 2>&1); then�[0m
 �[36;1m    echo "❌ [R5] $rf: not parseable YAML: $cfg"; total=$((total + 1)); continue�[0m
 �[36;1m  fi�[0m
 �[36;1m  if [ "$(jq -r 'type' <<<"$cfg")" != object ]; then�[0m
 �[36;1m    echo "❌ [R5] $rf: top-level must be a mapping"; total=$((total + 1)); continue�[0m
 �[36;1m  fi�[0m
 �[36;1m  rid=$(jq -r --arg b "$(basename "$rf")" 'if has("id") then .id | tostring else $b end' <<<"$cfg")�[0m
 �[36;1m  desc=$(jq -r '.description // ""' <<<"$cfg")�[0m
 �[36;1m  canon=$(jq -r '.canonical_pointer // ""' <<<"$cfg")�[0m
 �[36;1m  mapfile -t pats < <(jq -r '(.patterns // [])[]' <<<"$cfg")�[0m
 �[36;1m  mapfile -t includes < <(jq -r '((.scope // {}).include // [])[]' <<<"$cfg")�[0m
 �[36;1m  if [ "${#pats[@]}" -eq 0 ] || [ "${#includes[@]}" -eq 0 ]; then�[0m
 �[36;1m    echo "❌ [R5:$rid] missing patterns or scope.include in $rf"�[0m
 �[36;1m    total=$((total + 1)); continue�[0m
 �[36...

GitHub Actions: Governance / governance _ Security policy checks: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run set -uo pipefail
 �[36;1mset -uo pipefail�[0m
 �[36;1mDIR=.github/canonical-references�[0m
 �[36;1mif [ ! -d "$DIR" ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] no $DIR/ — skipped (repo has not opted in)"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1m# Rule files are read with yq, never a hand parser (YAML-POLICY Y-1); this�[0m
 �[36;1m# gate previously parsed them with Python, which the estate bans.�[0m
 �[36;1mif ! command -v yq >/dev/null 2>&1 || ! command -v jq >/dev/null 2>&1; then�[0m
 �[36;1m  echo "❌ [R5] yq and jq are required on the runner for YAML rule parsing"�[0m
 �[36;1m  exit 2�[0m
 �[36;1mfi�[0m
 �[36;1mmapfile -t files < <(find "$DIR" -maxdepth 1 -type f \( -name '*.yml' -o -name '*.yaml' \) ! -name '.*' | LC_ALL=C sort)�[0m
 �[36;1mif [ "${#files[@]}" -eq 0 ]; then�[0m
 �[36;1m  echo "ℹ️  [R5] $DIR/ has no .yml/.yaml rules — skipped"�[0m
 �[36;1m  exit 0�[0m
 �[36;1mfi�[0m
 �[36;1m�[0m
 �[36;1merr=$(mktemp)�[0m
 �[36;1mtrap 'rm -f "$err"' EXIT�[0m
 �[36;1mtotal=0�[0m
 �[36;1mfor rf in "${files[@]}"; do�[0m
 �[36;1m  if ! cfg=$(yq -o json '.' "$rf" 2>&1); then�[0m
 �[36;1m    echo "❌ [R5] $rf: not parseable YAML: $cfg"; total=$((total + 1)); continue�[0m
 �[36;1m  fi�[0m
 �[36;1m  if [ "$(jq -r 'type' <<<"$cfg")" != object ]; then�[0m
 �[36;1m    echo "❌ [R5] $rf: top-level must be a mapping"; total=$((total + 1)); continue�[0m
 �[36;1m  fi�[0m
 �[36;1m  rid=$(jq -r --arg b "$(basename "$rf")" 'if has("id") then .id | tostring else $b end' <<<"$cfg")�[0m
 �[36;1m  desc=$(jq -r '.description // ""' <<<"$cfg")�[0m
 �[36;1m  canon=$(jq -r '.canonical_pointer // ""' <<<"$cfg")�[0m
 �[36;1m  mapfile -t pats < <(jq -r '(.patterns // [])[]' <<<"$cfg")�[0m
 �[36;1m  mapfile -t includes < <(jq -r '((.scope // {}).include // [])[]' <<<"$cfg")�[0m
 �[36;1m  if [ "${#pats[@]}" -eq 0 ] || [ "${#includes[@]}" -eq 0 ]; then�[0m
 �[36;1m    echo "❌ [R5:$rid] missing patterns or scope.include in $rf"�[0m
 �[36;1m    total=$((total + 1)); continue�[0m
 �[36...

GitHub Actions: Governance / 7_governance _ Workflow security linter.txt: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run # GitHub Actions REJECTS a workflow with duplicate keys: the run is
 �[36;1m# GitHub Actions REJECTS a workflow with duplicate keys: the run is�[0m
 �[36;1m# `failure` with no jobs, no log and no check run. Nothing else here�[0m
 �[36;1m# can see it, because yaml.safe_load silently keeps the LAST�[0m
 �[36;1m# duplicate and reports success — so the file "parses" and every�[0m
 �[36;1m# other lint passes. Measured 2026-08-05: nine workflows in hypatia�[0m
 �[36;1m# were dead this way, including a CodeQL workflow with zero�[0m
 �[36;1m# successful runs in its entire lifetime.�[0m
 �[36;1mset -euo pipefail�[0m
 �[36;1mSCRIPT=".standards-dupkey/scripts/check-workflow-duplicate-keys.sh"�[0m
 �[36;1m# Self-hosting fallback: when THIS repository is standards, its own�[0m
 �[36;1m# working tree already holds the script, and during a rename that copy�[0m
 �[36;1m# is the only correct one — the pinned main checkout still has the old�[0m
 �[36;1m# name. Preferring the fetched copy keeps every other caller on the�[0m
 �[36;1m# canonical version.�[0m
 �[36;1mif [ ! -f "$SCRIPT" ] && [ -f scripts/check-workflow-duplicate-keys.sh ]; then�[0m
 �[36;1m  SCRIPT="scripts/check-workflow-duplicate-keys.sh"�[0m
 �[36;1m  echo "Using this repository's own copy (standards self-lint)."�[0m
 �[36;1mfi�[0m
 �[36;1mif [ ! -f "$SCRIPT" ]; then�[0m
 �[36;1m  echo "::error::duplicate-key checker not found — neither fetched from" \�[0m

GitHub Actions: Governance / governance _ Workflow security linter: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run # GitHub Actions REJECTS a workflow with duplicate keys: the run is
 �[36;1m# GitHub Actions REJECTS a workflow with duplicate keys: the run is�[0m
 �[36;1m# `failure` with no jobs, no log and no check run. Nothing else here�[0m
 �[36;1m# can see it, because yaml.safe_load silently keeps the LAST�[0m
 �[36;1m# duplicate and reports success — so the file "parses" and every�[0m
 �[36;1m# other lint passes. Measured 2026-08-05: nine workflows in hypatia�[0m
 �[36;1m# were dead this way, including a CodeQL workflow with zero�[0m
 �[36;1m# successful runs in its entire lifetime.�[0m
 �[36;1mset -euo pipefail�[0m
 �[36;1mSCRIPT=".standards-dupkey/scripts/check-workflow-duplicate-keys.sh"�[0m
 �[36;1m# Self-hosting fallback: when THIS repository is standards, its own�[0m
 �[36;1m# working tree already holds the script, and during a rename that copy�[0m
 �[36;1m# is the only correct one — the pinned main checkout still has the old�[0m
 �[36;1m# name. Preferring the fetched copy keeps every other caller on the�[0m
 �[36;1m# canonical version.�[0m
 �[36;1mif [ ! -f "$SCRIPT" ] && [ -f scripts/check-workflow-duplicate-keys.sh ]; then�[0m
 �[36;1m  SCRIPT="scripts/check-workflow-duplicate-keys.sh"�[0m
 �[36;1m  echo "Using this repository's own copy (standards self-lint)."�[0m
 �[36;1mfi�[0m
 �[36;1mif [ ! -f "$SCRIPT" ]; then�[0m
 �[36;1m  echo "::error::duplicate-key checker not found — neither fetched from" \�[0m

GitHub Actions: Governance / 9_governance _ Code quality + docs.txt: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run set -eo pipefail
 �[36;1mset -eo pipefail�[0m
 �[36;1m# Arming policy, and the evidence it rests on: standards#991.�[0m
 �[36;1m#�[0m
 �[36;1m#   retired-filename -> BLOCKS. A STABLE predicate:�[0m
 �[36;1m#   the retired `.a2ml` spelling of the launcher standard was�[0m
 �[36;1m#   deleted upstream on 2026-09-22�[0m
 �[36;1m#   (standards#952) and stays deleted, so a caller that is clean�[0m
 �[36;1m#   today cannot become defective without editing the citation�[0m
 �[36;1m#   itself. Measured 2026-09-22 over EVERY clone in the estate --�[0m
 �[36;1m#   595 scanned, 553 carrying an origin/main. 432 reference this�[0m
 �[36;1m#   reusable workflow, but only 12 do so at a MUTABLE ref (@main),�[0m
 �[36;1m#   and a new step reaches ONLY those 12: a caller pinned at a SHA�[0m
 �[36;1m#   freezes this whole file, this step included, so it can never�[0m
 �[36;1m#   receive the step at all. The real gate was run against all 12:�[0m
 �[36;1m#   12/12 rc=0, retired=0. Five slugs do carry the retired literal�[0m
 �[36;1m#   (tma-mark2, canonical-ums, the-nash-equilibrium,�[0m
 �[36;1m#   launch-scaffolder, trigger) and their overlap with the armed 12�[0m
 �[36;1m#   is ZERO -- so arming this tier reds ZERO live callers. A�[0m
 �[36;1m#   known-answer positive control fired (rc=1) on three of those�[0m
 �[36;1m#   defective repos through the identical harness, so the twelve�[0m
 �[36;1m#   zeros are a real measurement and not a broken probe.�[0m
 �[36;1m#�[0m
 �[36;1m#   stale-version -> WARNS, and does not block. A TIME-DEPENDENT�[0m
 �[36;1m#   predicate: the gate compares against its own CURRENT_VERSION, so�[0m
 �[36;1m#   every correctly-citing caller flips to defect the moment the�[0m
 �[36;1m#   standard bumps, having done nothing. A baked-in cutoff DATE does�[0m
 �[36;1m#   not cure that -- the #505 split above can use one because its�[0m
 �[36;1m#   missing-CONTRIBUTING population is static, while this population�[0m
 �[36;1m#   is regenerated at every...

GitHub Actions: Governance / governance _ Code quality + docs: feat(uuid-v7): exempt registry-assigned Julia dependency UUIDs

Conclusion: failure

View job details

##[group]Run set -eo pipefail
 �[36;1mset -eo pipefail�[0m
 �[36;1m# Arming policy, and the evidence it rests on: standards#991.�[0m
 �[36;1m#�[0m
 �[36;1m#   retired-filename -> BLOCKS. A STABLE predicate:�[0m
 �[36;1m#   the retired `.a2ml` spelling of the launcher standard was�[0m
 �[36;1m#   deleted upstream on 2026-09-22�[0m
 �[36;1m#   (standards#952) and stays deleted, so a caller that is clean�[0m
 �[36;1m#   today cannot become defective without editing the citation�[0m
 �[36;1m#   itself. Measured 2026-09-22 over EVERY clone in the estate --�[0m
 �[36;1m#   595 scanned, 553 carrying an origin/main. 432 reference this�[0m
 �[36;1m#   reusable workflow, but only 12 do so at a MUTABLE ref (@main),�[0m
 �[36;1m#   and a new step reaches ONLY those 12: a caller pinned at a SHA�[0m
 �[36;1m#   freezes this whole file, this step included, so it can never�[0m
 �[36;1m#   receive the step at all. The real gate was run against all 12:�[0m
 �[36;1m#   12/12 rc=0, retired=0. Five slugs do carry the retired literal�[0m
 �[36;1m#   (tma-mark2, canonical-ums, the-nash-equilibrium,�[0m
 �[36;1m#   launch-scaffolder, trigger) and their overlap with the armed 12�[0m
 �[36;1m#   is ZERO -- so arming this tier reds ZERO live callers. A�[0m
 �[36;1m#   known-answer positive control fired (rc=1) on three of those�[0m
 �[36;1m#   defective repos through the identical harness, so the twelve�[0m
 �[36;1m#   zeros are a real measurement and not a broken probe.�[0m
 �[36;1m#�[0m
 �[36;1m#   stale-version -> WARNS, and does not block. A TIME-DEPENDENT�[0m
 �[36;1m#   predicate: the gate compares against its own CURRENT_VERSION, so�[0m
 �[36;1m#   every correctly-citing caller flips to defect the moment the�[0m
 �[36;1m#   standard bumps, having done nothing. A baked-in cutoff DATE does�[0m
 �[36;1m#   not cure that -- the #505 split above can use one because its�[0m
 �[36;1m#   missing-CONTRIBUTING population is static, while this population�[0m
 �[36;1m#   is regenerated at every...
🔇 Additional comments (3)
docs/UUID-V7-ESTATE-STANDARD.adoc (1)

138-144: LGTM!

Also applies to: 157-160

scripts/check-uuid-v7.sh (1)

10-20: LGTM!

Also applies to: 50-50

scripts/tests/uuid-v7-test.sh (1)

61-77: LGTM!


📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Julia package manifests and dependency UUIDs in [deps], [weakdeps] and [extras] are no longer flagged by the UUID checker. Package-level UUIDs are still checked, and new estate packages must use UUID v7 before registration.
  • Tests
    • Added coverage for Julia project files, manifests and other TOML files.

Walkthrough

The UUID v7 standard and checker now exclude registry-assigned UUIDs in Julia dependency tables and manifests. The checker still evaluates a package’s top-level UUID. New tests cover these rules and their boundaries.

Changes

Julia UUID checker exclusions

Layer / File(s) Summary
Document and implement UUID exclusions
docs/UUID-V7-ESTATE-STANDARD.adoc, scripts/check-uuid-v7.sh, scripts/tests/uuid-v7-test.sh
The standard and checker exclude Julia manifest UUIDs and UUIDs in the [deps], [weakdeps] and [extras] tables of Julia project files. The checker continues to evaluate the package’s top-level UUID. Tests cover these exclusions and confirm that other UUIDs remain checked.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Feature

Suggested reviewers: joshuajewell

Merge Risk: 🔵 Low · up to 67e99

A Julia project can pass the UUID check despite having a non-v7 package UUID when a multiline string contains a dependency-table header. This narrow case warrants owner awareness but does not block merging.

Architecture Summary

Architecture risk: 🔵 Low · up to 67e99

The change affects 2 systems.

Changed systems: scripts, docs

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — scripts (service) was modified; 2 changed files map to changed impact.
  • observed — docs (service) was modified; 1 changed file maps to changed impact.

Before / after behavior

  • observed — Modified behavior in docs/UUID-V7-ESTATE-STANDARD.adoc: The standard identifies Julia project dependency tables and Julia manifests as checker exclusions because their package UUIDs are registry-assigned. A package’s own top-level uuid remains checked and must be v7 before first registration.
  • observed — Modified behavior in docs/UUID-V7-ESTATE-STANDARD.adoc: The revision history adds v1.1, recording the Julia dependency UUID exclusions and stating that repositories previously passing remain passing, while Julia repositories whose only findings were dependency UUIDs now pass; package-own UUIDs remain governed.
  • observed — Modified behavior in scripts/check-uuid-v7.sh: Added scannable_text, which outputs nothing for Julia manifest files, removes the [deps], [weakdeps] and [extras] tables from Julia project files, and passes other files through unchanged.
  • observed — Modified behavior in scripts/check-uuid-v7.sh: The UUID-match input now comes from scannable_text instead of directly grepping the file; the existing UUID pattern and empty-result fallback are unchanged.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. (1 skipped: 1 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the main change: exempting registry-assigned Julia dependency UUIDs from the UUID v7 check.
Description check ✅ Passed The description directly explains the Julia UUID exemption, the affected files, the tests, the governance requirements, and the migration impact.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
📝 Generate docstrings
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit checks each UUID line,
And leaves registry IDs behind.
The package’s own must meet the rule,
The tests check every table’s role.
The standard’s notes now match the tool.

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

sonarqubecloud Bot commented Oct 2, 2026

Copy link
Copy Markdown

@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

✅ Coding Agent task started: View task and status

The task will inspect the CI failures, validate its fix, and commit the fix to this branch automatically.

Note: Fixing CI failures is a beta feature and may encounter errors. Expect some limitations and changes as we gather feedback and continue to improve it.

⏭️ 3 check(s) skipped — already failing on `main` (not caused by this PR)
  • GitHub Actions: Governance / 0_governance _ Validate Hypatia Baseline.txt
  • GitHub Actions: Governance / 2_governance _ Well-Known (RFC 9116 + RSR).txt
  • GitHub Actions: Governance / 7_governance _ Workflow security linter.txt

@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Coding task changes are ready, but delivery needs attention

Open the task to resolve the delivery issue or retry.

@hyperpolymath
hyperpolymath merged commit 0ad1787 into main Oct 2, 2026
49 of 50 checks passed
@hyperpolymath
hyperpolymath deleted the feat/uuid-v7-julia-dependency-tables branch October 2, 2026 16:47
hyperpolymath added a commit to metadatastician/ZenodoDeposits.jl that referenced this pull request Oct 2, 2026
Replaces the AFFIRMATION.adoc template with a draft. The template's
placeholders are the only error from `call-estate-audit / estate-audit`
on main (run 37017560464). This addresses that box on #3.

**For your review: this is your statement, so edit it freely before
merging.**

Each claim was produced in this session at anchor `a68b585`:
- `Pkg.test()`: 377 pass, 1 skipped (the live sandbox test, which needs
a token). It includes Aqua and JET.
- `proofs/agda/check.sh` with Agda 2.6.4.3 and stdlib 2.1: type-checks
with `--safe --without-K` and no postulates.
- `proofs/agda/generate.jl` was re-run and gave no diff, so the proved
table is the code's table.

The *What we do NOT claim* section lists:
- no live deposit has been made;
- the Julia–Agda correspondence beyond the table is argued, not
formalised;
- the package is not yet registered;
- the remaining reds on #3;
- the tests ran on Julia 1.12.6 only.

The audit's placeholder regex (`\{\{|rsr-template-repo|TODO:
update|<PROJECT|YOUR_PROJECT|lorem ipsum|example\.com`) is clean on this
file and matches the template (control).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01JPmNukJT5PUzQ9d74mhHhj

### Deferred red checks (§5c)
Each of these checks was already red on `main` before this PR. Each one
is tracked on #3:
- `lint-workflows`: tracked on #3, fixed by #6 (unpinned reusables on
main)
- `call-estate-audit / estate-audit`: tracked on #3. On `main` it fails
with "AFFIRMATION.adoc contains template placeholders", which this PR
fixes. On this PR it fails at a different step:
`cicd-suite/actions/affirmation-check/check.sh` treats `%G?`=`E` (the
signature cannot be checked) as a bad signature. The runner checks out
GitHub's synthetic merge commit 34f875a. That commit is PGP-signed with
GitHub's key, which the runner does not hold. The head commit c1d835f
(then b4e528b) is `verified: true` on GitHub. The fix belongs in
cicd-suite; it is the owner's decision.
- `governance / UUID v7 conformance`: tracked on #3, fixed by
hyperpolymath/standards#1138, then #8
- `Julia nightly - ubuntu-latest`: tracked on #3, fixed by #9
- `SonarQube`: tracked on #3, fixed by the owner creating the SonarCloud
project

**Caveat (unmeasured):** merging this probably will not turn
`estate-audit` green on `main`. GitHub signs the squash commit with its
own key, so the same checker is likely to read `%G?`=`E` there too.
Clearing it needs the cicd-suite fix (owner decision; see #3).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
hyperpolymath added a commit to metadatastician/ZenodoDeposits.jl that referenced this pull request Oct 2, 2026
Fixes the `lint-workflows` red tracked on #3 ("reusable workflow calls
not SHA-pinned").

## What changes
- Six `hyperpolymath/standards` reusable calls are pinned from `@main`
to `e2e0f6d61c2d2a36ef516849dc1ca9223563479f`, which was standards
`main` on 2026-10-02. The six are governance, scorecard, codeql,
secret-scanner, hypatia-scan and mirror.
- The `cicd-suite` `main-estate-audit` call is pinned to
`5087cbb080cd6c5e9a79fee3fcc20acd82431bb4`, which was cicd-suite `main`
on 2026-10-02.
- `actions: read` is granted to the scorecard caller, at both the
workflow and job level, and to the mirror caller, at the workflow level.
Their pinned reusables request that scope. A reusable workflow cannot
elevate past its caller, so without the grant those jobs fail at
startup. I think this also explains the OSSF Scorecard `startup_failure`
on #3. That is a hypothesis, which the Scorecard run on this PR will
confirm or refute.

`actions.lock` is unchanged. Its entries for these callers are already
`[]`. The pages workflow is not touched, because a separate PR handles
it.

## Checks run locally
- `gh actions-lock --no-fix` exits 0, and its output is identical to
main's.
- Every workflow file parses as YAML.
- No `uses: …@main` remains in `.github/workflows`.

Refs #3

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01JPmNukJT5PUzQ9d74mhHhj

### Deferred red checks (§5c)
Each of these checks was already red on `main` before this PR. Each one
is tracked on #3:
- `call-estate-audit / estate-audit`: tracked on #3. #5 fixes main's
placeholder error (#5's own run is blocked by a separate cicd-suite
affirmation-check issue: the signature state `E`)
- `governance / UUID v7 conformance`: tracked on #3, fixed by
hyperpolymath/standards#1138, then #8
- `Julia nightly - ubuntu-latest`: tracked on #3, fixed by #9
- `SonarQube`: tracked on #3, fixed by the owner creating the SonarCloud
project

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
hyperpolymath added a commit to metadatastician/ZenodoDeposits.jl that referenced this pull request Oct 2, 2026
Part of the UUID v7 conformance red on #3. Owner decision 2026-10-02:
re-mint the package UUID as v7 now, while that is still possible.

## What changes
- `Project.toml`: `uuid` changes from
`928c34ec-c44f-4801-ad1c-d3b833d76a91` (v4) to
`01a0fd25-08dc-75f2-9446-d9ab13218ca1` (v7, from `UUIDs.uuid7()` on
Julia 1.12.6). The General registry fixes a package's UUID at first
registration, so this is the last chance to change it.
- `docs/Project.toml`: same UUID update in its `[deps]` entry for the
package.
- `test/runtests.jl:508`: the fixture bucket id is now a v7-shaped
literal. The test still exercises the same refusal of a bucket on
another host.

## Status of the UUID check
This PR does **not** turn `governance / UUID v7 conformance` green on
its own. The remaining findings are dependency UUIDs assigned by the
registry. They need hyperpolymath/standards#1138, which narrows the
checker and is awaiting review by both estate owners. After #1138
merges, the governance caller pin has to move to the merge commit,
because the reusable checks out the validator at `job.workflow_sha`.

## Checks run locally
- `Pkg.test()`: 377 pass, 1 broken. The broken entry is the opt-in live
sandbox test, which was skipped.
- The checker from standards#1138 (`check-uuid-v7.sh .`) exits 0 on this
tree.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01JPmNukJT5PUzQ9d74mhHhj

### Deferred red checks (§5c)
Each of these checks was already red on `main` before this PR. Each one
is tracked on #3:
- `call-estate-audit / estate-audit`: tracked on #3. #5 fixes main's
placeholder error (#5's own run is blocked by a separate cicd-suite
affirmation-check issue: the signature state `E`)
- `governance / UUID v7 conformance`: tracked on #3, fixed by
hyperpolymath/standards#1138, then #8
- `Julia nightly - ubuntu-latest`: tracked on #3, fixed by #9
- `SonarQube`: tracked on #3, fixed by the owner creating the SonarCloud
project

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
hyperpolymath added a commit to metadatastician/ZenodoDeposits.jl that referenced this pull request Oct 2, 2026
Closes the "Julia nightly" item on #3 by its second done-criterion: the
nightly job is now reported as allowed to fail.

- **What changes:** the job name changes from `Julia nightly -
ubuntu-latest` to `Julia nightly (allowed to fail) - ubuntu-latest`, and
a comment gives the reason.
- **Unchanged:** the job was already `continue-on-error: true`, and it
still runs. It still shows red while upstream is broken. Nothing is
hidden.
- **The upstream cause, on main run 37024620408:** JuliaInterpreter does
not precompile on nightly (`MethodError: no method matching
nteltype(::Core.SimpleVector)`), so JET is skipped.
- **No stranded check:** `rules/branches/main` returns `[]`, so no
required context refers to the old name.
- **Local checks:** the workflow parses as YAML, and `gh actions-lock
--no-fix` exits 0.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01JPmNukJT5PUzQ9d74mhHhj

### Deferred red checks (§5c)
Each of these checks was already red on `main` before this PR. Each one
is tracked on #3:
- `call-estate-audit / estate-audit`: tracked on #3. #5 fixes main's
placeholder error (#5's own run is blocked by a separate cicd-suite
affirmation-check issue: the signature state `E`)
- `governance / UUID v7 conformance`: tracked on #3, fixed by
hyperpolymath/standards#1138, then #8
- `Julia nightly (allowed to fail) - ubuntu-latest`: tracked on #3,
fixed by this PR (the job is renamed to say it is allowed to fail; the
upstream red stays visible)
- `lint-workflows`: tracked on #3, fixed by #6
- `SonarQube`: tracked on #3, fixed by the owner creating the SonarCloud
project

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
hyperpolymath added a commit to metadatastician/ZenodoDeposits.jl that referenced this pull request Oct 2, 2026
…INTAINERS (#12)

After the transfer to `metadatastician`, `call-estate-audit /
estate-audit` (required-files-check) fails on main ee687b7:
`MAINTAINERS never mentions the repository owner (metadatastician)`.

This adds one sentence to `MAINTAINERS` and `MAINTAINERS.adoc` naming
the owning organisation; @hyperpolymath stays the maintainer (owner
decision 2026-10-02: transfer intended, add the org owner). It is
independent of #11 (URLs) and touches no file #11 touches.

Local check of the gate predicate (`grep -qiF metadatastician`): passes
on both files here, fails on both on main (control).

Measured on this PR: the Required Files step now passes, and
estate-audit fails only at the Affirmation Document Gate, where the
GitHub-signed commit reads `E`. That is fixed at source in
hyperpolymath/cicd-suite#39 (draft, for review), but it reaches this
repo only after three steps:
1. cicd-suite#39 merges.
2. cicd-suite repins its composites at that merge
(hyperpolymath/cicd-suite#40).
3. This repo bumps `call-estate-audit` from `5087cbb` to the repin's
merge SHA, plus any `actions.lock` entry the bump needs.

Until then, `call-estate-audit / estate-audit` stays red for that reason
alone.

The other reds here are not caused by this PR and are tracked elsewhere:
- Actions lockfile verify: the relock after Dependabot #10.
- UUID v7 conformance: hyperpolymath/standards#1138.
- OSSF Scorecard: the shared standards workflow.

All of them are listed on #3.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01JPmNukJT5PUzQ9d74mhHhj

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant