Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 52 additions & 14 deletions sync/deploy-clade-a2ml.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ deploy_clade() {
local lineage="$4"
local parent="$5"
local description="$6"
# Forge owner/org hosting this repo. Optional in repos.a2ml; parse-repos.sh
# defaults it to "hyperpolymath", so existing entries are unaffected.
local owner="${7:-hyperpolymath}"

local repo_path="$REPOS_DIR/$repo_name"

Expand All @@ -68,17 +71,52 @@ deploy_clade() {
return
fi

# Skip if CLADE.a2ml already exists
if [[ -f "$repo_path/.machine_readable/CLADE.a2ml" ]]; then
echo "ALREADY: $repo_name"
((ALREADY++))
# Skip if CLADE.a2ml already exists.
#
# Check BOTH known layouts. Two are in use across the estate and the canon
# does not yet agree which is authoritative:
# .machine_readable/CLADE.a2ml — this script + the CLADE-001 contractile
# .machine_readable/descriptiles/CLADE.a2ml — rsr-template-repo + chronicles-of-slavia
# Checking only the first meant a repo using the descriptiles layout looked
# like it had no CLADE at all, so this script would write a SECOND one — two
# files, two identities, no error. That disagreement is unresolved and is the
# owner's to settle; until then, refusing to write over an existing
# declaration is the safe reading.
local existing
for existing in "$repo_path/.machine_readable/CLADE.a2ml" \
"$repo_path/.machine_readable/descriptiles/CLADE.a2ml"; do
if [[ -f "$existing" ]]; then
echo "ALREADY: $repo_name (${existing#$repo_path/})"
((ALREADY++))
return
fi
done

# Generate deterministic UUID v5.
#
# The owner segment is part of the derived name, so it is part of the
# IDENTITY — get it wrong and the repo gets a uuid that belongs to nothing.
# It was hardcoded to "hyperpolymath", which silently produced a wrong uuid
# for any repo hosted elsewhere (e.g. the metadatastician org). Now sourced
# from the registry entry, still defaulting to "hyperpolymath" so every
# existing entry derives byte-identically.
local uuid
uuid=$(uuidgen --sha1 --namespace @url --name "github.com/$owner/$repo_name")

# Fail loudly if the registry disagrees with the repo's actual remote — a
# silently wrong owner means a silently wrong identity, which is worse than
# no identity at all.
local remote_owner
remote_owner=$(git -C "$repo_path" remote get-url origin 2>/dev/null \
| sed -nE 's#^(https?://[^/]+/|[^@]+@[^:]+:)([^/]+)/.*$#\2#p')
if [[ -n "$remote_owner" && "$remote_owner" != "$owner" ]]; then
echo "WARN: $repo_name — registry says owner='$owner' but origin says '$remote_owner'." >&2
echo " The uuid is derived FROM the owner, so one of them is wrong." >&2
echo " Set 'owner = \"$remote_owner\"' in repos.a2ml, or fix the remote. Skipping." >&2
((FAILED++))
return
fi

# Generate deterministic UUID v5
local uuid
uuid=$(uuidgen --sha1 --namespace @url --name "github.com/hyperpolymath/$repo_name")

# Determine prefixed name
local prefixed="${primary}-${repo_name}"

Expand All @@ -94,7 +132,7 @@ deploy_clade() {
[identity]
uuid = "$uuid"
primary-forge = "github"
primary-owner = "hyperpolymath"
primary-owner = "$owner"
canonical-name = "$repo_name"
prefixed-name = "$prefixed"

Expand All @@ -105,9 +143,9 @@ assigned = "2026-03-16"
rationale = "$description"

[forges]
github = "hyperpolymath/$repo_name"
gitlab = "hyperpolymath/$repo_name"
bitbucket = "hyperpolymath/$repo_name"
github = "$owner/$repo_name"
gitlab = "$owner/$repo_name"
bitbucket = "$owner/$repo_name"

[lineage]
type = "$lineage"
Expand Down Expand Up @@ -148,8 +186,8 @@ echo "Repos dir: $REPOS_DIR"
[[ "$DRY_RUN" == "--dry-run" ]] && echo "MODE: DRY RUN"
echo ""

while IFS=$'\t' read -r name primary secondary lineage parent description; do
deploy_clade "$name" "$primary" "$secondary" "$lineage" "$parent" "$description"
while IFS=$'\t' read -r name primary secondary lineage parent description owner; do
deploy_clade "$name" "$primary" "$secondary" "$lineage" "$parent" "$description" "$owner"
done < <(parse_repos)

echo ""
Expand Down
13 changes: 10 additions & 3 deletions sync/export-json.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,19 @@ BEGIN { printf "[\n" }
NR > 1 { printf ",\n" }
{
name = $1; primary = $2; secondary = $3; lineage = $4; parent = $5; desc = $6
owner = ($7 != "" ? $7 : "hyperpolymath")
gsub(/"/, "\\\"", desc)
# Generate UUID deterministically
cmd = "uuidgen --sha1 --namespace @url --name \"github.com/hyperpolymath/" name "\""
# Generate UUID deterministically. The owner segment is part of the derived
# name, so it is part of the identity; it was hardcoded to "hyperpolymath",
# which produced a wrong uuid for any repo hosted elsewhere. Defaults to
# "hyperpolymath", so entries without an explicit owner are unchanged.
cmd = "uuidgen --sha1 --namespace @url --name \"github.com/" owner "/" name "\""
cmd | getline uuid
close(cmd)
printf " {\"name\":\"%s\",\"uuid\":\"%s\",\"clade\":\"%s\",\"secondary\":%s,\"lineage\":\"%s\",\"parent\":\"%s\",\"description\":\"%s\",\"prefixed\":\"%s-%s\",\"github\":\"hyperpolymath/%s\"}", name, uuid, primary, secondary, lineage, parent, desc, primary, name, name
# NB: no separate "owner" key — the schema is unchanged on purpose. The
# github field already carries it as "owner/name", so entries without an
# explicit owner serialise byte-identically to before this change.
printf " {\"name\":\"%s\",\"uuid\":\"%s\",\"clade\":\"%s\",\"secondary\":%s,\"lineage\":\"%s\",\"parent\":\"%s\",\"description\":\"%s\",\"prefixed\":\"%s-%s\",\"github\":\"%s/%s\"}", name, uuid, primary, secondary, lineage, parent, desc, primary, name, owner, name
}
END { printf "\n]\n" }
' > "$OUT/repos.json"
Expand Down
26 changes: 22 additions & 4 deletions sync/parse-repos.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: MPL-2.0
# Parse repos.a2ml and emit TSV: name\tprimary\tsecondary\tlineage\tparent\tdescription
# Parse repos.a2ml and emit TSV:
# name\tprimary\tsecondary\tlineage\tparent\tdescription\towner
#
# `owner` is the forge owner/org that hosts the repo. It is OPTIONAL in
# repos.a2ml and defaults to "hyperpolymath", so every existing entry parses
# exactly as before and derives exactly the same uuid. Set it per-entry only for
# repos hosted elsewhere:
#
# [repo.cadastra]
# primary = "rm"
# owner = "metadatastician"
#
# It is the LAST column: consumers that read only the first six fields are
# unaffected by its presence.

# Default to this repo's seed file (script lives in sync/, seed in verisim/seed/).
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
Expand All @@ -10,14 +23,14 @@ awk '
BEGIN { FS="=" }
/^\[repo\./ {
if (current_repo != "") {
printf "%s\t%s\t%s\t%s\t%s\t%s\n", current_repo, primary, secondary, lineage, parent, description
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", current_repo, primary, secondary, lineage, parent, description, owner
}
line = $0
gsub(/^\[repo\./, "", line)
gsub(/\]$/, "", line)
gsub(/"/, "", line)
current_repo = line
primary = ""; secondary = "[]"; description = ""; lineage = "standalone"; parent = ""
primary = ""; secondary = "[]"; description = ""; lineage = "standalone"; parent = ""; owner = "hyperpolymath"
}
current_repo != "" && /^primary / {
val = $2
Expand All @@ -44,9 +57,14 @@ current_repo != "" && /^parent / {
gsub(/^ *"/, "", val); gsub(/".*$/, "", val)
parent = val
}
current_repo != "" && /^owner / {
val = $2
gsub(/^ *"/, "", val); gsub(/".*$/, "", val)
owner = val
}
END {
if (current_repo != "") {
printf "%s\t%s\t%s\t%s\t%s\t%s\n", current_repo, primary, secondary, lineage, parent, description
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", current_repo, primary, secondary, lineage, parent, description, owner
}
}
' "$SEED_FILE"
Loading