Repository navigation
ci: follow standards to metadatastician; port the template's CI - #15
Conversation
hyperpolymath/standards moved to metadatastician/standards. A reusable
`uses:` does not follow the rename, and a hyperpolymath repository cannot
call a reusable in metadatastician's repository (rsr-template-repo#253
measured it: every caller failed at startup). Governance, Rust CI,
Hypatia and Secret Scanner had stopped loading ("workflow was not found").
Ports rsr-template-repo's CI from 60cedf1 to 8034fc9, its last green main
commit, by a three-way apply of the template's own diff over .github,
scripts, tests, .machine_readable, verification, build/container and the
K9 records, then the mint's self-name pass, as a mint would:
- self-contained workflows checking out metadatastician/standards@8e48b1c;
- squabble, proven-tests and fork-governance workflows; deed and K9
validation move into Dogfood Gate;
- KYAML container config (data unchanged, rendered with this repo's
values and canonicalised by kyaml-format.sh), K9 contract v1.0.0
records, a JCS-canonical aibdp schema;
- CLAUDE.md regenerated by the arrival pack; the template's lock plus
proofs.yml.
Not ported: the generator tests (use-this-template mint, template-pin
resolver, e2e mint tests), which exercise repo-init.just. Known gap: the
self-contained governance runs one policy step where the reusable ran 19
jobs (UUID v8 conformance, licence consistency, lockfile verify, ratchets,
JS runtimes); they return when standards is callable again.
tests/workflows/actions_lock_sha_refs_test.sh now checks every SHA-keyed
record in the lock against an exact table, keeps all its negative
controls, and refuses any reusable call into the moved repository.
ffi_strings_test.sh and container_kyaml_test.sh join mint-verbatim.txt:
they are token fixtures the placeholder gate otherwise rejects.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LiQzWJdcPfRU6YMDGRG8Xi
|
Important Review skippedToo many files! This PR contains 123 files, which is 23 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.
|
|
SonarCloud Code Analysis failed: "B Security Rating on New Code (required ≥ A)".
Generated by Claude Code |
The proven-tests workflow's bench lane needs benches/baseline.json, which the port left behind: it sits outside the paths ported in d8878e5. Ported from rsr-template-repo 60cedf1..8034fc9 with template_bench.sh, the same three-way apply. run-proven-suite.sh --bench now passes locally, both bench lanes included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LiQzWJdcPfRU6YMDGRG8Xi
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
The proven suite's FFI lane failed: tests/ffi_strings_test.sh names the
template's functions by filling `{{project}}` with test_project, so it only
works while main.zig still carries the token. In a minted repository the
functions are resource_algebra_*, and the appended tests named nothing.
The test now reads the export prefix from `export fn <prefix>_init()` after
filling the tokens and maps it to test_project, failing loudly when no
prefix is found. Checked on this tree and on the template's tokenised
main.zig: all six functions the tests call resolve.
src/interface/ffi/src/main.zig takes the template's 8034fc9 version (the
ownership docs and the string tests the lane exercises), with the mint's
values filled in as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LiQzWJdcPfRU6YMDGRG8Xi
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7a003d9c0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for (const [ctx, relWf] of mapped.entries()) { | ||
| const fullWf = join(root, relWf); | ||
| if (!existsSync(fullWf)) { | ||
| fail(`required context '${ctx}' maps to missing workflow '${relWf}'`); | ||
| continue; | ||
| } | ||
| const doc = Bun.YAML.parse(readFileSync(fullWf, "utf8")); |
There was a problem hiding this comment.
Verify that the mapped workflow emits the named context
For each mapping, this gate only parses the workflow trigger; it never checks that a job whose check-run name is ctx actually exists and can run. If scan / gitleaks is renamed or its job is removed while secret-scanner.yml remains PR-triggered, this script still exits successfully even though the required context can never be produced, leaving affected PRs stranded behind branch protection. Inspect the workflow's jobs and match the effective job/check name as part of this loop.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed. Fixed in #16: each mapped context now also needs a job whose check-run name (name:, or the job id) equals it. A renamed-job mutant and a no-jobs mutant now fail squabble_gate_test.sh.
Generated by Claude Code
| for p in &out { | ||
| if p.is_dir() { | ||
| return Err(format!( | ||
| "{} is a directory; pass files (e.g. `git ls-files | {} -`)", | ||
| p.display(), | ||
| "strip-instruction-blocks" | ||
| )); |
There was a problem hiding this comment.
Update repo-init to pass files to the stripping tool
The rewritten tool now explicitly rejects directory arguments, but build/just/repo-init.just still invokes strip-instruction-blocks . under set -e. Consequently every non-template just repo-init reaches this check with . as a directory, receives exit 2, and aborts before completing the mint; the new file-list mode needs to be wired into that caller.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed. Fixed in #16, which replaces build/just/repo-init.just with the template's at 8034fc9, verbatim. That copy pipes the mint's file list to strip-instruction-blocks -.
Generated by Claude Code
| # Read by build/just/repo-init.just (mint_files) and by | ||
| # scripts/check-no-placeholders.sh. One repository-relative path per line; `#` | ||
| # starts a comment. A listed path that does not exist stops the mint: a stale | ||
| # entry is a hole, not a no-op. |
There was a problem hiding this comment.
Make repo-init honor the verbatim manifest
Despite this declaration, repo-wide search shows that only scripts/check-no-placeholders.sh reads this manifest; build/just/repo-init.just still runs its placeholder and self-name rewrites over every text file and retains its old hard-coded exemptions. On a mint, listed fixtures such as julia_library_test.sh and self_name_pass_test.sh are therefore rewritten even though the new checker subsequently exempts them, reproducing the broken-child behavior this manifest is intended to prevent. Load one validated file list in repo-init and exclude it from every rewrite and completeness pass.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed. The port kept the older generator. #16 brings the template's 8034fc9 repo-init.just, which loads .machine_readable/mint-verbatim.txt as VERBATIM_LIST and excludes it from the rewrite and completeness passes.
Generated by Claude Code
| MODE=index | ||
| if [ "${1:-}" = "--worktree" ]; then MODE=worktree; shift; fi | ||
| REPO_ROOT="${1:-.}" |
There was a problem hiding this comment.
Use worktree mode when generating a freshly minted map
The new mode is specifically required before a child's first commit, but build/just/repo-init.just still calls gen-repo-map.sh ., which leaves MODE=index. At that point the index still contains paths repo-init removed and omits newly created paths, so the generated repository map is stale immediately and the child's Estate Rules freshness check fails after the first commit. Pass --worktree from the mint-time caller.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed. Fixed by the same generator update in #16: the mint now calls gen-repo-map.sh --worktree ..
Generated by Claude Code
| CONFIG=".gitleaks-estate.toml" | ||
| if [ -f .gitleaks.toml ]; then | ||
| CONFIG=".gitleaks.toml" |
There was a problem hiding this comment.
Keep the estate rules when loading repository secret rules
On pull-request runs, the checkout contains contributor-controlled content, so adding .gitleaks.toml makes these lines discard the staged estate baseline and pass only that local file to --config. In Gitleaks 8.18.4, --config has highest precedence and the default rules are used only when no config is supplied; inheritance must be explicitly configured with [extend] (Gitleaks 8.18.4 documentation). A minimal local rule set can therefore make scan / gitleaks pass while generic credentials are missed; keep the trusted baseline mandatory and merge validated repository additions into it instead of replacing it.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed. Fixed in #16: the estate baseline now runs in all three passes, and a repository .gitleaks.toml adds a second pass but can never replace the baseline.
Tested with pinned gitleaks 8.18.4: a planted key plus a local config that allowlists every path exits 1 with the new step and 0 with the old selection. The template carries the same code, so I'm leaving this thread open for the owner.
Generated by Claude Code
|
Add Carrot credits or activate Agent usage billing to use Autofix |
main's b11b3bc has the same tree as #15's head 2d5f150, so conflicts resolve to this branch. The CHANGELOG keeps #15's entry as merged and records the review fixes in their own entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LiQzWJdcPfRU6YMDGRG8Xi
## Summary Follow-up to #15, which merged while its Codex review was still being answered. This PR fixes the five findings that were real defects. The other two are answered below. ## Changes - **`build/just/repo-init.just`.** Codex threads: the `strip-instruction-blocks` P1, the mint-verbatim P1 and the `gen-repo-map` P2. - #15 ported the template's mint scripts but kept the older generator, the template's `0afa6c9` copy. - That generator called `strip-instruction-blocks .`, which the new tool rejects with exit 2. It also ignored `mint-verbatim.txt` and mapped the index instead of the worktree. - The generator is now the template's at `8034fc9`, verbatim, which is how `mint-verbatim.txt` says a child carries it. It feeds the tool a file list, honours the manifest and passes `gen-repo-map.sh --worktree`. - **`secret-scanner.yml`.** Codex thread: P1, security. - Before, a repository `.gitleaks.toml` replaced the estate baseline in all three passes, so a pull request could add a permissive local config and pass. - Now the baseline always runs, and a local config adds a second pass. - **`scripts/check-required-contexts.sh`.** Codex thread: P2. - A mapped context now also needs a job whose check-run name (`name:`, or the job id) is exactly that context. - `squabble_gate_test.sh` names its fixture jobs after the context, so each mutant still fails only for its own defect. Two mutants are new: a renamed job and a workflow with no jobs. - **`main-estate-audit.yml`.** Codex thread: P2. - At the pinned `bf7dd95`, cicd-suite's `spdx-license-check` enforces only a root licence file. When the repository has no SPDX line at all, it emits a `::warning::`; its exit is commented out "until adoption". - The inlined step already enforced the same thing. It now carries the warning too, so it mirrors that gate exactly. Per-file SPDX enforcement does not exist upstream, and adding it is a licence-policy decision for the owner, so it is not added here. - **CHANGELOG.** A new entry. #15's entry stays as merged. **Not changed: `container.just` deploy rendering (Codex P2).** - `container-init` is a one-shot: it fills tokens, then renames `deploy.k9.ncl.in`. - In this repository it has already run, and every container file is rendered. Re-running it changes no file, `deploy.k9.ncl` included, which takes the recipe's "already exists, not overwritten" branch. - So shipping the `.in` here would only reintroduce a token file into a minted child. ## RSR Quality Checklist ### Required - [ ] Tests pass (`just test` or equivalent). Not run in full: `just test` and `just quality` stop locally at the idris2 and zig steps, because neither toolchain is installed here. CI provisions both. Every suite this PR touches passes; see Testing. - [x] Code is formatted (`just fmt` or equivalent) - [x] Linter is clean (no new warnings or errors) - [x] No banned language patterns (no Python, Go, TypeScript, Deno or ReScript; JavaScript runs on Bun) - [x] No `unsafe` blocks without `// SAFETY:` comments - [x] No banned functions (`believe_me`, `unsafeCoerce`, `Obj.magic`, `Admitted`, `sorry`) - [x] SPDX license headers present on all new/modified source files - [x] No secrets, credentials, or `.env` files included ### As Applicable - [x] `CHANGELOG` or release notes updated ## Testing - **Gitleaks 8.18.4,** sha256-verified as the workflow pins it, run through the workflow's own working-tree step: - Planted AWS-shaped key plus a local `.gitleaks.toml` that allowlists every path: the new step exits 1. The old selection, which used only the local config, exits 0. - Clean tree, with and without the local config: the new step exits 0. - **Required contexts:** a renamed-job fixture fails the new gate (exit 1) and passed the old one (exit 0). - `squabble_gate_test.sh` reports 81 passed and 0 failed. - `mint_cleanup_test.sh`, `archetype_lock_merge_test.sh`, `repo_map_determinism_test.sh`, `run_proven_suite_test.sh`, `validate_workflows_test.sh` and `actions_lock_sha_refs_test.sh` pass, the last with yq 4.53.3. - `check-no-placeholders.sh` passes, `just --list` parses with the new generator, and `gen-repo-map.sh --worktree` leaves the map unchanged. --- _Generated by [Claude Code](https://claude.ai/code/session_01LiQzWJdcPfRU6YMDGRG8Xi)_ --------- Co-authored-by: Claude <noreply@anthropic.com>




Summary
hyperpolymath/standardsmoved tometadatastician/standards. Four workflows stopped loading because of it: Governance, Rust CI, Hypatia and Secret Scanner (workflow was not found; see #14).uses:does not follow the rename.This PR ports rsr-template-repo's CI from
60cedf1(the canary state) to8034fc9, its last green main commit. Template main has been red since a run of direct file renames on 2026-10-26, which are not ported here.Changes
.github,scripts,tests,.machine_readable,verification,build/containerand the K9 records. Then the mint's self-name pass, run exactly asrepo-init.justdefines it. Conflicts were resolved toward the template, exceptestate-rules.yml, which keeps this repository's own tests.metadatastician/standards@8e48b1c.squabble.yml,proven-tests.ymlandfork-governance.yml.deed-validate.ymlandk9-validate.ymlgo, as the template did in #247.kyaml-format.sh, and its parsed data is byte-identical to before.deploy.k9.nclis re-rendered at K9 contract v1.0.0.coordination.k9.nclandsession/custom-checks.k9.nclgaincomponent_type.actions.lockis the template's lock plusproofs.yml.actions_lock_sha_refs_test.shlost its subject: governance no longer calls a standards reusable. It now checks every SHA-keyed record in the lock against an exact table (tag, owner and repo IDs), keeps all its negative controls, and refuses any reusable call into the moved repository. Planted regressions fail it as intended.ffi_strings_test.shandcontainer_kyaml_test.shjoinmint-verbatim.txt. They are token fixtures, which the placeholder gate otherwise rejects.build/just/repo-init.just, and this port does not bring the generator.Known gap, by owner decision
The self-contained governance runs one policy step. The reusable it replaces ran 19 jobs, among them UUID v8 conformance, licence consistency, actions-lockfile verify, the debt and exemption ratchets and the JS runtime checks. They come back when the owner makes
metadatastician/standardscallable from hyperpolymath; the template has the same gap.Template defects found on the way (not fixed here)
container-initrenders the container KYAML without reformatting it. A freshly minted child therefore fails "Converted YAML stays KYAML".mint-verbatim.txtomitstests/ffi_strings_test.shandtests/workflows/container_kyaml_test.sh. A fresh child fails the placeholder gate.LICENSEtoLICENSE.adocandCODEOWNERStoCODEOWNERS.adoc.RSR Quality Checklist
Required
just testor equivalent)just fmtor equivalent)unsafeblocks without// SAFETY:commentsbelieve_me,unsafeCoerce,Obj.magic,Admitted,sorry).envfiles includedAs Applicable
CHANGELOGor release notes updatedTesting
Run locally, with yq 4.53.3 sha256-verified as CI installs it:
tests/workflows/*.shandtests/shape/*.shpasses.check-lock-sync.shreports the lock in sync and transitively closed.metadatastician/standards@8e48b1c: 15 K9 files, 0 failing.kyaml-format.sh --checkpasses on all three container files.check-ijson-jcs.sh --enforce: 12 of 12 files canonical.check-required-contexts.sh,check-no-placeholders.sh,check-root-shape.sh, the repository-map determinism test andcheck-adoc-renders.shall pass.validate-template.sh: 0 errors.check-agda.sh: all proofs and the 8 rejections pass.Generated by Claude Code