diff --git a/.github/workflows/proven-tests.yml b/.github/workflows/proven-tests.yml index fb802367..f07c1405 100644 --- a/.github/workflows/proven-tests.yml +++ b/.github/workflows/proven-tests.yml @@ -49,6 +49,7 @@ jobs: run: | bun scripts/atlas/census-atlas.mjs check bun test tests/atlas/census-atlas.test.mjs + bash tests/census/build_rows_status_test.sh - name: Install verified Nickel 1.18.0 (K9 L2 semantics) run: | set -euo pipefail diff --git a/docs/architecture/REPOSITORY-MAP.adoc b/docs/architecture/REPOSITORY-MAP.adoc index d28ba7e4..e2cc583c 100644 --- a/docs/architecture/REPOSITORY-MAP.adoc +++ b/docs/architecture/REPOSITORY-MAP.adoc @@ -117,6 +117,10 @@ predecessors did. | yes | - +| `applied-systems/` +| yes +| owner-requested reusable applications area (2026-11-07) + | `benches/` | optional | Cargo-conventional at package root @@ -204,6 +208,11 @@ your own repo - but do not read their emptiness as neglect here. | `.machine_readable/bot_directives/` | `.machine_readable/descriptiles/anchors/` | `.machine_readable/scripts/verification/` +| `applied-systems/decision-science/` +| `applied-systems/finance/` +| `applied-systems/finance/cohort-economics/` +| `applied-systems/finance/liquidity/` +| `applied-systems/organisational-design/` | `docs/governance/audit/` | `docs/governance/audit/compliance/` | `docs/governance/audit/effects/` diff --git a/mathesis_chora.deed b/mathesis_chora.deed index 5b1c7339..ddb2e296 100644 --- a/mathesis_chora.deed +++ b/mathesis_chora.deed @@ -30,9 +30,9 @@ ; equal canon.lock [canon.artifacts]; canon.lock [canon.lockstep].order is ; spine-adopts-then-canon-releases, so this clause moves FIRST. (canon - :version "2.1.3" + :version "2.1.5" :criteria-sha256 "6a5aa8857bd0d0d58ef48827938ca17c251b6b854dacf59d306388d61694d82a" - :gates-sha256 "2f31f46d4753432e0aa8c9c28f339e18e062c98dc6e6ef4ecbb76993cf37638b" + :gates-sha256 "5c510bba025be718deebb12d0333bfe7db2da43c66578b728b1a334df65290b1" :lockstep-since "2026-09-17" ; A canon change this repo cannot satisfy is a change made in the WRONG ; ORDER, not a rejected change: land the spine's adoption first, then the diff --git a/scripts/census/build-rows.sh b/scripts/census/build-rows.sh index 67b8e15b..23f8ea93 100644 --- a/scripts/census/build-rows.sh +++ b/scripts/census/build-rows.sh @@ -37,7 +37,18 @@ jq -r '[.repo,.file,.class]|@tsv' "$R/holes.jsonl" \ jq -r '[.repo,.file]|@tsv' "$R/decls.jsonl" \ | awk -F'\t' 'NR==FNR{t[$1]=1;next} !($2 in t){print $1}' "$T" - > "$tmp/decls.tsv" -jq -r '.repo+"\t"+.path' "$R/repos-with-status.jsonl" | sort > "$tmp/status.tsv" +# One status document per repository. A PROOF-STATUS file is the per-claim +# record PROOF-POLICY §8.5 names (grades and recheck legs), so it wins over +# PROOF-NEEDS (obligations) and proof-debt; within a rank the first path in +# byte order (LC_ALL=C, so the choice does not depend on the locale) wins. +# Sorting on the path alone picked docs/status/PROOF-NEEDS.adoc over +# docs/status/PROOF-STATUS.adoc. +jq -r '.repo+"\t"+.path' "$R/repos-with-status.jsonl" \ +| awk -F'\t' 'BEGIN{OFS="\t"} { + b=$2; sub(/.*\//, "", b); b=toupper(b) + rank = (b ~ /^PROOF-STATUS/) ? 0 : (b ~ /^PROOF-NEEDS/) ? 1 : 2 + print $1, rank, $2 }' \ +| LC_ALL=C sort -t$'\t' -k1,1 -k2,2n -k3,3 | cut -f1,3 > "$tmp/status.tsv" awk -F'\t' ' FILENAME ~ /holes\.tsv$/ { h[$1" "$2]++; next } diff --git a/tests/census/build_rows_status_test.sh b/tests/census/build_rows_status_test.sh new file mode 100644 index 00000000..a2098514 --- /dev/null +++ b/tests/census/build_rows_status_test.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: MPL-2.0 +# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell +# +# build-rows.sh picks one proof-status document per repository. A +# PROOF-STATUS file (the PROOF-POLICY §8.5 per-claim record) must win over +# PROOF-NEEDS and proof-debt, even where its path sorts later; without +# PROOF-STATUS, PROOF-NEEDS wins over proof-debt; within a kind, the first +# path in byte order (LC_ALL=C) wins. +set -euo pipefail +root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)" +work="$(mktemp -d)"; trap 'rm -rf "$work"' EXIT +fail=0 + +printf '%s\n' \ + '{"ext":"agda","path":"A.agda","repo":"a/needs-sorts-first"}' \ + '{"ext":"agda","path":"A.agda","repo":"b/needs-over-debt"}' \ + '{"ext":"agda","path":"A.agda","repo":"c/debt-only"}' \ + '{"ext":"agda","path":"A.agda","repo":"d/two-status"}' > "$work/files.jsonl" +printf '%s\n' \ + '{"path":"docs/status/PROOF-NEEDS.adoc","repo":"a/needs-sorts-first"}' \ + '{"path":"docs/status/PROOF-STATUS.adoc","repo":"a/needs-sorts-first"}' \ + '{"path":"proof-debt.adoc","repo":"b/needs-over-debt"}' \ + '{"path":"docs/PROOF-NEEDS.adoc","repo":"b/needs-over-debt"}' \ + '{"path":"proofs/proof-debt.md","repo":"c/debt-only"}' \ + '{"path":"docs/status/PROOF-STATUS.adoc","repo":"d/two-status"}' \ + '{"path":"PROOF-STATUS.adoc","repo":"d/two-status"}' > "$work/repos-with-status.jsonl" +: > "$work/holes.jsonl"; : > "$work/decls.jsonl" +# A template list that matches nothing (an empty file would make build-rows' +# NR==FNR idiom swallow the first real input). +echo 'no/such/template/path' > "$work/template-paths.txt" + +rows="$(bash "$root/scripts/census/build-rows.sh" "$work" "$work/template-paths.txt")" +expect() { + local repo="$1" want="$2" got + got="$(jq -r --arg r "$repo" '.[] | select(.repo == $r) | .status_doc' <<< "$rows")" + if [ "$got" = "$want" ]; then + echo "PASS: $repo -> $want" + else + echo "FAIL: $repo -> got '$got', want '$want'" >&2 + fail=1 + fi +} +expect a/needs-sorts-first docs/status/PROOF-STATUS.adoc +expect b/needs-over-debt docs/PROOF-NEEDS.adoc +expect c/debt-only proofs/proof-debt.md +expect d/two-status PROOF-STATUS.adoc + +(( fail == 0 )) && echo 'PASS: build-rows status-document preference' || exit 1