Skip to content

fix(a2ml): correct peek/char, and make the ipkg header state the truth - #562

Merged
hyperpolymath merged 681 commits into
mainfrom
fix/a2ml-parser-charat-and-honest-ipkg
Jul 29, 2026
Merged

fix(a2ml): correct peek/char, and make the ipkg header state the truth#562
hyperpolymath merged 681 commits into
mainfrom
fix/a2ml-parser-charat-and-honest-ipkg

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Answers gitar-bot's comment on #555. The bot was right that the documented command fails — but its diagnosis was incomplete and its suggested remedy (soften the comment / scope the module list) would have made the claim less true.

Measured: idris2 --typecheck a2ml-core.ipkgexit 1, 16 errors (Idris2 0.7.0).

1. Code fix. 2 of the 16 shared one root cause: strIndex : String -> Int -> Char is partial and returns a bare Char; peek and char pattern-matched it as Just/Nothing. Added a total bounds-checked charAt : String -> Nat -> Maybe Char. 16 → 14.

2. Honest header. The remaining 14 are real and now documented in the file: 7 totality, 5 unification, 1 undefined <|>, 1 private collectIds.

And the part that matters most: the header claimed this package makes SPEC.adoc §3.1 "machine-checked" and referred to "the CI job that consumes this". No workflow in this repository invokes it. The claim was decorative — exactly the fake gate the next paragraph of that same header warns about.

🤖 Generated with Claude Code

hyperpolymath and others added 30 commits May 31, 2026 08:29
…t (post #275 closeout cleanup) (#328)

## Summary

Surfaced during the standards#275 STEP 7 closeout **estate-wide hypatia
scan**: `proven-servers/bindings/rescript/package-lock.json` was the
single uncarved hit across 20 estate-wide `package-lock.json` files.

[hypatia#412](hyperpolymath/hypatia#412) extends
the `:nodejs_detected` rule's class 5c
(`/bindings/{javascript,typescript}/`) to also cover
`/bindings/rescript/`. This PR **mirrors that to the
LANGUAGE-POLICY.adoc Node.js narrative row**, matching the docs-vs-rule
parity pattern from hypatia#405 + standards#320.

## Change

`rhodium-standard-repositories/spec/LANGUAGE-POLICY.adoc` Node.js
banned-language row:

| Before | After |
|---|---|
| "nine carve-out classes (six original + three added during the
migration via hypatia#405)" | "nine carve-out classes (six original +
three added during the migration via hypatia#405 + one added
post-closeout via hypatia#412 for `/bindings/rescript/` symmetry)" |
| Class (5): `**/bindings/{javascript,typescript}/**` | Class (5):
`**/bindings/{javascript,typescript,rescript}/**` with rationale "the
`rescript` variant is host-required for the rescript-to-js compile
chain" |

## Why post-closeout

The standards#253 closeout PR (#325) merged 2026-05-31T07:11Z. The
campaign is officially complete. This PR makes the closeout declaration
"zero `:nodejs_detected` flags outside carve-outs" **exactly true** (was
19/20 prior) without re-opening #253 or #275.

Pairs with hyperpolymath/hypatia#412 (rule update + test). Both should
land together to maintain docs↔rule parity.

## Test plan

- [ ] CI green (text-only change)
- [ ] Cross-link to hypatia#412 PR description visible in this PR
comments
- [ ] Hypatia self-scan unchanged (rule is in hypatia repo, not
standards)

Refs #253 (umbrella, CLOSED 2026-05-31)
Refs #275 (STEP 7, CLOSED 2026-05-31)
Refs #320 (predecessor mirror PR pattern for hypatia#405)
Refs hyperpolymath/hypatia#412 (the rule update this mirrors)

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- C001: CodeQL language fixes
- C002: License identifier standardization
- C003: Outdated actions audit
- C004: Pin standards refs to SHA 861b5e9
- C005: Add workflow-level permissions
## Summary

Adds R5b to the `security-policy` job in `governance-reusable.yml`,
right alongside R0 / R1 (where the existing tooling-version integrity
rules live).

Hard-blocks `Version: x.y.z` / `**Version**: x.y.z` / `_Version_=
v1.2.3` patterns in repo-root `*.md` + `*.adoc` files (excluding
`CHANGELOG.{md,adoc}`). Defers all version state to `CHANGELOG.md`
(release history), `Cargo.toml`'s `[package].version` (semver pin), and
the git log (dates).

## Why now

echidna shipped this exact rule locally last week as
`governance-doc-drift.yml` R5b
([echidna#171](hyperpolymath/echidna#171)). The
drift pattern that motivated it — `Version: 1.5.0` in `README.adoc`,
`**Version**: 2.3.0` in `CLAUDE.md`, `2.1.0` in `Cargo.toml`, all
simultaneously — generalises to every long-lived repo.

## Scope decision

R5b only (version strings). R5a (bare prover counts) stays repo-local in
echidna because the count semantics are domain-specific (prover backends
vs. stdlib functions vs. proof obligations vs. syntax features). A
future generic R5 with per-repo configurable canonical patterns is the
natural extension, but R5b stands alone today.

Sub-tree docs (`docs/handover/`, `docs/decisions/`, `docs/releases/`,
audit reports) deliberately out of scope — owner-managed snapshots, not
the canonical narrative surface.

## Baseline scan results

- **standards** (this repo): 0 hits ✓
- **proven**: 0 hits ✓
- **ephapax**: 0 hits ✓
- **affinescript**: 0 hits ✓
- **typed-wasm**: 0 hits ✓

Estate-wide rollout is safe — no caller repo will be retroactively
broken.

## Self-tested

- `python3 -c "import yaml; yaml.safe_load(...)"` → OK
- Negative test (synthetic):
  - `*Version*: 1.2.3` → fires ✓
  - `Version: v0.5.0` → fires ✓
  - `**Version**= 9.9.9` → fires ✓
- `This is v1.2.3 software.` → correctly does NOT fire (no `Version:`
prefix anchored)

## Downstream rollout

Caller repos consume by bumping their `governance.yml` wrapper SHA pin.
echidna can also drop its local R5b (keeping R5a) once it bumps the pin.
Cohort fan-out will follow this change.

## Test plan

- [x] YAML safe_load OK
- [x] Self-test on this repo's root docs → 0 hits
- [x] Negative test on synthetic drift → fires
- [x] Baseline-scan on 4 cohort repos → 0 hits each
- [ ] CI on this PR
- [ ] Downstream caller-repo SHA-pin bumps (echidna + cohort)

Refs hyperpolymath/echidna#171.
…330)

## Summary

Adds a config-driven R5 step to the `security-policy` job in
`governance-reusable.yml`. Each caller repo declares its own
canonical-reference rules via
`.github/canonical-references/*.{yml,yaml}`; the step skips silently
when the directory is absent so repos opt in by creating it.

Rule file shape:

```yaml
id: short-slug
description: one-line summary
patterns:
  - 'POSIX-ERE regex 1'
  - 'POSIX-ERE regex 2'
canonical_pointer: path/to/single-source-of-truth.md
scope:
  include:
    - README.adoc
    - CLAUDE.md
    # …
```

POSIX-ERE semantics preserved via `grep -E`; YAML parsing via `python3`
+ PyYAML (standard on `ubuntu-latest`). Matches emit `::error
file=...,line=...::` annotations and fail the job.

## Why

Generalises echidna's R5a (bare prover counts → `docs/PROVER_COUNT.md`)
so sibling repos with their own canonical-reference cohorts can declare
drift patterns without carrying a per-repo workflow file:

- **proven**: lemma counts → `PROOF_STATUS.md`
- **affinescript**: stdlib fn counts → `STDLIB.md`
- **typed-wasm**: proof-obligation counts → `docs/PROOF_COUNT.md`
- **ephapax**: rule counts → `RULES.md`

R5b (estate-wide hardcoded version-string check) stays separate. The two
coexist: R5b is universal, R5 generic covers per-repo patterns.

## Self-tested

- ✅ YAML safe_load on the modified workflow
- ✅ Embedded heredoc Python compiles via `compile()` (58 lines, no
SyntaxError)
- ✅ Local exercise on synthetic config + drift docs: `128 prover
backends` + `144 ProverKind variants` both fire on line 2; `Tier-1
prover backends` correctly does NOT fire (anchoring preserved); clean
doc → 0 hits
- ✅ Backward-compat: standards itself has no
`.github/canonical-references/` → step exits 0 with `ℹ️ [R5] no
.github/canonical-references/ — skipped`

## Promotion roadmap

1. **(this PR)** Generic R5 lands in standards.
2. echidna migrates R5a into
`.github/canonical-references/prover-counts.yml` and deletes
`governance-doc-drift.yml`.
3. Cohort repos adopt incrementally as their canonical-reference docs
stabilise.

## Test plan

- [x] YAML safe_load OK
- [x] Embedded Python compiles
- [x] Negative test (synthetic drift) fires
- [x] Positive test (no config) skips silently
- [ ] CI on this PR — `governance / Security policy checks` green

Refs hyperpolymath/echidna#171, refs #329.
…closes #322) (#334)

## Summary

\`rust-ci-reusable.yml\` lines 109 and 149 used a bare \`if:\`
expression at job level:

\`\`\`yaml
if: hashFiles(format('{0}/Cargo.toml', inputs.working_directory)) != ''
\`\`\`

GH Actions silently fails to parse the entire CALLER workflow when this
exact shape (`hashFiles(format(inputs.X))` bare at job-level) is reached
in a reusable. Caller manifests as 0s-duration "completed failure" with
the workflow name reported as the path (`.github/workflows/rust-ci.yml`)
instead of the YAML `name:` field — GitHub's "This run likely failed
because of a workflow file issue" diagnostic.

## Root-cause investigation

Run on panic-attack#95 (experiment branch, 5 commits), tracking the
parsed workflow `name` field via API:

| commit | caller pin | caller shape | reusable | parsed name | result |
|---|---|---|---|---|---|
| `1d0a8b9` | `@cc5a372` | original thin wrapper |
`rust-ci-reusable.yml` | path-fallback | ❌ fail |
| `d022c8f` | `@main` | original thin wrapper | `rust-ci-reusable.yml` |
path-fallback | ❌ fail |
| `02c6753` | `@main` | governance.yml shape | `rust-ci-reusable.yml` |
path-fallback | ❌ fail |
| `6250e19` | `@main` | governance.yml shape |
**`governance-reusable.yml`** | `'Rust CI'` ✓ | parses (fails at
runtime, expected) |
| `cb23224` | `@main` | governance.yml verbatim clone |
`governance-reusable.yml` | `'Rust CI'` ✓ | parses |

Falsifies #322 hypotheses 1+2+3:
- Hypothesis 1 (caller structure) — falsified: changing the caller's
YAML to match governance.yml verbatim did NOT fix.
- Hypothesis 2 (SHA resolution) — falsified: `@main` floating ref ALSO
failed.
- Hypothesis 3 (workflow_id cache) — falsified: a fresh \`workflow_id\`
287101574 (created via filename rename) ALSO failed.

Root cause: hypothesis 4 (new) — when the caller's \`uses:\` resolves to
a reusable whose first job has a bare \`if: hashFiles(format(...))\` at
job level, GH's expression evaluator rejects the resolution at
workflow-parse time. The audit + coverage jobs (lines 187, 215) were
always wrapped in \`\${{ }}\` and worked; the check + test jobs were
not.

## The fix

Two-line `if:` wrapping. Diff:

\`\`\`diff
- if: hashFiles(format('{0}/Cargo.toml', inputs.working_directory)) !=
''
+ if: \${{ hashFiles(format('{0}/Cargo.toml', inputs.working_directory))
!= '' }}
\`\`\`

## Estate impact

Once this merges, every caller of \`rust-ci-reusable.yml\` should
immediately start parsing on its next push — no caller-side action
needed for callers using \`@main\` floating refs. SHA-pinned callers
will need to bump the pin to a commit at-or-after this merge.

## Follow-up

- 43+ panic-attack-tracked callers using SHA-pinned rust-ci-reusable.yml
— bumping their pins to the new commit could be a fan-out, but a no-op
SHA bump is sufficient once \`@main\` resolution is confirmed clean.
- Audit other reusables (\`governance-reusable.yml\`,
\`secret-scanner-reusable.yml\`, etc.) for the same anti-pattern via
grep: \`^\\s*if: [^$]\` followed by \`hashFiles\\|format\\|inputs\\.\` —
none found in governance-reusable on inspection but worth a sweep.

## Refs

- Closes #322
- Investigation PR (panic-attack side): hyperpolymath/panic-attack#95
- Original symptom report PRs: panic-attack#84 (orphan-SHA hypothesis,
falsified), panic-attack#92 (SHA-bump experiment, falsified)

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ecard/secret-scanner) (#335)

## Summary
The canonical wrappers in this repo (\`scorecard.yml\`, \`mirror.yml\`,
\`secret-scanner.yml\`) self-pinned the **birth SHA** of each reusable
from 2026-05-26, even after meaningful reusable updates landed:

- **mirror-reusable**: #305 added the Radicle secret-presence gate
(\`af5cd0cabd\`) that fixes 26 repos' \`mirror-radicle\` red (e.g.
ephapax#268). The canonical was still demonstrating a pre-gate pin, so
downstream wrappers that mirror this pin couldn't pick up the fix.
- **scorecard-reusable**: #230 aligned canonical cron + #249 SPDX
migration (\`e03686486e\`). Cosmetic, but unblocks the canonical
demonstrating current shape.
- **secret-scanner-reusable**: #236 pragma-honoring fix (\`28fdf197\`) +
#249 SPDX.

Bumps all 3 to standards@main HEAD \`3f34549c\` so the canonical example
reflects the current reusable shape that downstream wrappers should
converge to.

## Fan-out implication
Downstream wrappers currently pinning the 2026-05-26 birth SHAs can now
mechanically refresh their pins to match. Worth its own follow-up
campaign; this PR is the prerequisite (canonical-first).

## Test plan
- [x] All 3 SHAs resolve to existing commits in this repo
- [ ] standards' own scorecard / mirror / secret-scanner runs on PR +
post-merge

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-pattern as #322/#334) (#336)

## Summary

Same root cause as #322 / #334 — \`elixir-ci-reusable.yml:105\` had a
bare \`if:\` at job level containing \`hashFiles(format('{0}/mix.exs',
inputs.working_directory))\`. Surfaced via the sweep recipe from #334:

\`\`\`bash
grep -nE '^\\s+if: [^\$]+(hashFiles|format|inputs\\.)'
.github/workflows/*-reusable.yml
\`\`\`

Only hit — every other reusable is clean. Same 2-line `\${{ }}` wrap.

## Test plan

- [x] Sweep recipe returns no remaining hits across reusables
- [x] yamllint clean
- [x] Pattern matches #334's exact diff shape

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary

Adds a short `== Reference implementations` subsection at the end of
`cartridges/CARTRIDGE-FORMAT.adoc` pointing implementers at the live
downstream consumer of this format.

The cartridge format here is now consumed by
`hyperpolymath/boj-server-cartridges`, which serves as the canonical
registry (already referenced in `<<Registry and on-demand fetch>>`) and
exercises the schema across every shipped cartridge. New section gives
implementers a worked example to read.

## Rationale

Downstream landed three pieces of machinery worth pointing at from the
spec:

- A SHA-pinned mirror of `cartridge-v1.json` at `schemas/` with
`PINNED-SHA` + `SCHEMA-MIRROR.md` documenting the refresh discipline.
- A zero-dep Deno validator at `tools/validate-cartridges/` (only
`jsr:@std/fs` + `jsr:@std/path` + `jsr:@std/assert`) with `audit` /
`audit-verbose` / `strict` / `test` tasks.
- A blocking CI gate at `.github/workflows/cartridge-schema.yml`; strict
mode went live 2026-06-01 after 139/139 manifests passed.

Subsection is ~28 lines, doesn't restate the spec, and clarifies that
downstreams pin by SHA rather than tracking `main` — bumps follow the
procedure in downstream's `schemas/SCHEMA-MIRROR.md`.

## Test plan

- [ ] AsciiDoc renders cleanly (manual review of the new subsection).
- [ ] No other content modified — diff is a pure append at end-of-file.

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary

Formalises the deterministic SPDX-FileCopyrightText injector originally
prototyped in `/tmp` during the valence-shell 2026-06-01 M1 closure
session (where it drove an 8-batched 267-file copyright sweep across
valence-shell PRs #95-#102).

Lifted from one-off tmp script to proper standards estate tool: 5
comment styles, 3 modes, robust against the prototype's `printf --` /
`grep --` parsing bugs, idempotent, 18-case regression test.

## What it does

For each input file (positional args, `--files <list>`, or stdin),
checks:

- **Already has Copyright line** → skip
- **Has SPDX line but no Copyright** → insert Copyright line on line
after SPDX
- **Neither present** → prepend a fresh comment block

## Modes

| Mode | Behaviour | Exit code |
|---|---|---|
| `--apply` (default) | Write changes | 0 on success |
| `--check` | Don't write, exit 1 if any would change | 0 = clean / 1 =
changes pending |
| `--dry-run` | Print what would change, don't write | 0 = clean / 1 =
changes pending |

## Comment style autodetection (override with `--style`)

| Style | Extensions |
|---|---|
| `html` | .md .html .htm .xml .svg .vue .astro |
| `slash` | .rs .c .h .cpp .hpp .cc .hh .zig .js .ts .tsx .jsx .go
.swift .kt .scala .java .cs .dart .v .sv .adoc .asciidoc .css .scss
.sass .less |
| `dash` | .idr .hs .lhs .sql .lean .elm .purs .ada .vhdl |
| `hash` | .ex .exs .py .rb .pl .pm .sh .bash .zsh .fish .yml .yaml
.toml .r .tcl .jl .nix (+ Makefile, Dockerfile, .gitignore, .envrc,
.editorconfig) |
| `semi` | .lisp .scm .ss .el .clj .cljs .cljc .rkt |

## Customisation

Required: `SPDX_COPYRIGHT_HOLDER` env var or `--holder NAME`
Optional: `SPDX_LICENSE` env var or `--license ID` (defaults to MPL-2.0)

## Test plan

- [x] `scripts/tests/spdx-inject-copyright-test.sh` exercises 18 cases,
all passing locally
- [x] Style autodetection per extension
- [x] Idempotence (running twice == running once)
- [x] `--check` exits 1 when changes pending; 0 when clean
- [x] `--dry-run` never modifies
- [x] Missing file: counted but not an error
- [x] Unknown extension: skipped silently
- [x] Regression: file content lines starting with `--` (the bug
discovered in the Idris2 batch during the prototype run)
- [x] `--files` flag + stdin input
- [x] Missing `--holder` → exit 2
- [x] `--style` override on unknown extension

## Why now

The valence-shell sweep used `/tmp/spdx-sweep/inject-copyright.sh` (a
less polished version). Estate-wide SPDX sweeps will follow the same
pattern; lifting this means future sweeps can rely on a tested,
portable, idempotent, CI-ready tool rather than rediscovering the same
edge cases.

## Wiring

Not yet wired into `governance-reusable.yml` (governance only invokes
scripts that check policy; this script also writes). Could be wired as
an optional `spdx-inject-check` job using `--check` mode if desired —
left as a follow-up for the owner.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nd_yarn group across 1 directory (#332)

Bumps the npm_and_yarn group with 1 update in the /lol directory:
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).

Updates `vitest` from 2.1.9 to 4.1.8
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases">vitest's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.8</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>browser</strong>:
<ul>
<li>Disable client <code>cdp</code> API when <code>allowWrite/allowExec:
false</code> [backport to v4]  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Codex</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10450">vitest-dev/vitest#10450</a>
<a href="https://github.com/vitest-dev/vitest/commit/e4067b3b1"><!-- raw
HTML omitted -->(e4067)<!-- raw HTML omitted --></a></li>
<li>Remove orphaned Playwright route when same module is mocked via
multiple ids [backport to v4]  -  by <a
href="https://github.com/toxik"><code>@​toxik</code></a> and <a
href="https://github.com/Zelys-DFKH"><code>@​Zelys-DFKH</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10474">vitest-dev/vitest#10474</a>
<a href="https://github.com/vitest-dev/vitest/commit/675b4343f"><!-- raw
HTML omitted -->(675b4)<!-- raw HTML omitted --></a></li>
</ul>
</li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.7...v4.1.8">View
changes on GitHub</a></h5>
<h2>v4.1.7</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>runner</strong>: Limit concurrency per task branch in
addition to per leaf callbacks (backport)  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10384">vitest-dev/vitest#10384</a>
<a href="https://github.com/vitest-dev/vitest/commit/4f0f2a1ee"><!-- raw
HTML omitted -->(4f0f2)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.6...v4.1.7">View
changes on GitHub</a></h5>
<h2>v4.1.6</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>browser</strong>: Provide project reference in
<code>ToMatchScreenshotResolvePath</code>  -  by <a
href="https://github.com/macarie"><code>@​macarie</code></a> and <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10138">vitest-dev/vitest#10138</a>
<a href="https://github.com/vitest-dev/vitest/commit/31882607c"><!-- raw
HTML omitted -->(31882)<!-- raw HTML omitted --></a></li>
<li>Global <code>sequence.concurrent: true</code> with top-level
<code>test(..., { concurrent: false })</code> + depreacte
<code>sequential</code> test API and options  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a>,
<strong>Codex</strong> and <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10196">vitest-dev/vitest#10196</a>
<a href="https://github.com/vitest-dev/vitest/commit/2847dfa2a"><!-- raw
HTML omitted -->(2847d)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>: Simplify orchestrator otel carrier  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10285">vitest-dev/vitest#10285</a>
<a href="https://github.com/vitest-dev/vitest/commit/18af98cee"><!-- raw
HTML omitted -->(18af9)<!-- raw HTML omitted --></a></li>
</ul>
<h3>   🏎 Performance</h3>
<ul>
<li>Stringify diff objects only once  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10276">vitest-dev/vitest#10276</a>
<a href="https://github.com/vitest-dev/vitest/commit/9f7b1528c"><!-- raw
HTML omitted -->(9f7b1)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.5...v4.1.6">View
changes on GitHub</a></h5>
<h2>v4.1.5</h2>
<h3>   🚀 Experimental Features</h3>
<ul>
<li><strong>coverage</strong>: Istanbul to support
<code>instrumenter</code> option  -  by <a
href="https://github.com/BartWaardenburg"><code>@​BartWaardenburg</code></a>
and <a
href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10119">vitest-dev/vitest#10119</a>
<a href="https://github.com/vitest-dev/vitest/commit/0e0ff41c7"><!-- raw
HTML omitted -->(0e0ff)<!-- raw HTML omitted --></a></li>
</ul>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>--project negation excludes browser instances  -  by <a
href="https://github.com/felamaslen"><code>@​felamaslen</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10131">vitest-dev/vitest#10131</a>
<a href="https://github.com/vitest-dev/vitest/commit/9423dc084"><!-- raw
HTML omitted -->(9423d)<!-- raw HTML omitted --></a></li>
<li>Project color label on html reporter  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10142">vitest-dev/vitest#10142</a>
<a href="https://github.com/vitest-dev/vitest/commit/596f73986"><!-- raw
HTML omitted -->(596f7)<!-- raw HTML omitted --></a></li>
<li>Fix <code>vi.defineHelper</code> called as object method  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10163">vitest-dev/vitest#10163</a>
<a href="https://github.com/vitest-dev/vitest/commit/122c25b5b"><!-- raw
HTML omitted -->(122c2)<!-- raw HTML omitted --></a></li>
<li>Alias <code>agent</code> reporter to <code>minimal</code>  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10157">vitest-dev/vitest#10157</a>
<a href="https://github.com/vitest-dev/vitest/commit/663b99fe3"><!-- raw
HTML omitted -->(663b9)<!-- raw HTML omitted --></a></li>
<li>Respect diff config options in soft assertions  -  by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a>,
<strong>sheremet-va</strong> and <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/8696">vitest-dev/vitest#8696</a>
<a href="https://github.com/vitest-dev/vitest/commit/9787dedad"><!-- raw
HTML omitted -->(9787d)<!-- raw HTML omitted --></a></li>
<li>Respect diff config options in soft assertions &quot;  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/8696">vitest-dev/vitest#8696</a>
<a href="https://github.com/vitest-dev/vitest/commit/7dc6d54fd"><!-- raw
HTML omitted -->(7dc6d)<!-- raw HTML omitted --></a></li>
<li><strong>ast-collect</strong>: Recognize _<em>vi_import</em> prefix
in static test discovery  -  by <a
href="https://github.com/Yejneshwar"><code>@​Yejneshwar</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10129">vitest-dev/vitest#10129</a>
<a href="https://github.com/vitest-dev/vitest/commit/325463ab2"><!-- raw
HTML omitted -->(32546)<!-- raw HTML omitted --></a></li>
<li><strong>coverage</strong>: Descriptive error message when reports
directory is removed during test run  -  by <a
href="https://github.com/DaveT1991"><code>@​DaveT1991</code></a> and <a
href="https://github.com/AriPerkkio"><code>@​AriPerkkio</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10117">vitest-dev/vitest#10117</a>
<a href="https://github.com/vitest-dev/vitest/commit/1413382e1"><!-- raw
HTML omitted -->(14133)<!-- raw HTML omitted --></a></li>
<li><strong>snapshot</strong>: Increase default snapshot max output
length  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Codex</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10150">vitest-dev/vitest#10150</a>
<a href="https://github.com/vitest-dev/vitest/commit/21e66ff63"><!-- raw
HTML omitted -->(21e66)<!-- raw HTML omitted --></a></li>
<li><strong>ui</strong>: Fix jsx/tsx syntax highlight  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10152">vitest-dev/vitest#10152</a>
<a href="https://github.com/vitest-dev/vitest/commit/f1b1f6c7b"><!-- raw
HTML omitted -->(f1b1f)<!-- raw HTML omitted --></a></li>
<li><strong>web-worker</strong>: Support MessagePort objects referenced
inside postMessage data  -  by <a
href="https://github.com/whitphx"><code>@​whitphx</code></a> and
<strong>Claude Opus 4.6 (1M context)</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/9927">vitest-dev/vitest#9927</a>
and <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10124">vitest-dev/vitest#10124</a>
<a href="https://github.com/vitest-dev/vitest/commit/7ad7d39af"><!-- raw
HTML omitted -->(7ad7d)<!-- raw HTML omitted --></a></li>
<li><strong>api</strong>: Make test-specification options writable  - 
by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10154">vitest-dev/vitest#10154</a>
<a href="https://github.com/vitest-dev/vitest/commit/6abd557b7"><!-- raw
HTML omitted -->(6abd5)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.4...v4.1.5">View
changes on GitHub</a></h5>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitest-dev/vitest/commit/e61f2dd2a0ba0a266c1c5e0334aad3799fee527f"><code>e61f2dd</code></a>
chore: release v4.1.8</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/e4067b3b150005fd42cf75f994300119245806b9"><code>e4067b3</code></a>
fix(browser): disable client <code>cdp</code> API when
<code>allowWrite/allowExec: false</code> [ba...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/a09d47236e19fd3151351080c667036ca6164dc4"><code>a09d472</code></a>
chore: release v4.1.7</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/a8fd24c1cad2320b19fcc651413c7d928423bdc1"><code>a8fd24c</code></a>
chore: release v4.1.6</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/18af98cee1830604d57f6a02bf28f8067cdffc06"><code>18af98c</code></a>
fix(browser): simplify orchestrator otel carrier (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10285">#10285</a>)</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/31882607cc67c7bf52ead13a606321ffdb06a857"><code>3188260</code></a>
feat(browser): provide project reference in
<code>ToMatchScreenshotResolvePath</code> (#...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/e399846850fedf10b8228cbe46a419628998acd9"><code>e399846</code></a>
chore: release v4.1.5</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/7dc6d54fd9dda0fe6fee2fb6451d0611a9ecb6e7"><code>7dc6d54</code></a>
Revert &quot;fix: respect diff config options in soft assertions (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/8696">#8696</a>)&quot;</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/9787dedade9896a6d3eeed7739177d6c583a68a7"><code>9787ded</code></a>
fix: respect diff config options in soft assertions (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/8696">#8696</a>)</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/325463ab292c45c3ef27aa21ec7da380c307052c"><code>325463a</code></a>
fix(ast-collect): recognize _<em>vi_import</em> prefix in static test
discovery (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10">#10</a>...</li>
<li>Additional commits viewable in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.8/packages/vitest">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for vitest since your current version.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=vitest&package-manager=npm_and_yarn&previous-version=2.1.9&new-version=4.1.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/hyperpolymath/standards/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Mirrors hyperpolymath/hyperpolymath#20.

Adds `zotpress/**` to the ReScript Exemptions table in
`.claude/CLAUDE.md` as an upstream-fork carve-out. This formalises the
per-repo `.hypatia-ignore` entry estate-wide so future-cloned hypatia
instances inherit the rule via `hypatia/scanner_suppression` without
needing per-repo configuration.

zotpress is an upstream WordPress plugin fork
(`hyperpolymath/hyperpolymath/zotpress`) — not estate-authored, kept in
tree as a vendored fork.

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#339)

## Summary

- Top-of-file `## License Policy — Manual Only (highest-priority
guardrail)` section in `.claude/CLAUDE.md`.
- Quotes the verbatim owner directive 2026-06-02 + 5-way classification
table.
- Hard rules for agents: no licence-change PRs without owner approval,
no bulk SPDX sweeps, no touching third-party headers, flag-only
findings.
- Canonical source pointers: memory files + hypatia rule + gitbot-fleet
dispatcher gate + fix-script refusal banners.

## Why

Owner directive 2026-06-02 forbids automated licence/SPDX edits.
Triggered by
[neurophone#99](hyperpolymath/neurophone#99) —
an auto-generated PR by the Claude bot reverting PMPL-1.0-or-later →
MPL-2.0 across ~140 files, closed by the owner. The CLAUDE.md guardrail
makes the policy discoverable to every agent that reads project context
before acting.

Verbatim:
> "mpl-2.0 is for my sole repos, all rights reserved is for 007,
agpl-3.0-or-later is for those shared with my son, and leave other
people's forked stuff alone … only palimpsest license for obvious
reasons should be talking about palipsest and palimpsest plasma, and
consent-aware-http, but in that case prospectively"

## Test plan

- [ ] Section renders correctly at the top of `.claude/CLAUDE.md`.
- [ ] Five-way classification table is intact and readable.
- [ ] Cross-references to gitbot-fleet/hypatia PRs land alongside this
one.

Related: hyperpolymath/gitbot-fleet chore/halt-license-auto-prs,
hyperpolymath/hypatia rules/license-no-auto-fix.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ired JVM shims) (#340)

Branch with 1 commit ahead of main; no PR previously opened. Filed
during 2026-06-02 estate orphan-branch sweep.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Workflow-level `permissions: read-all` capped the GITHUB_TOKEN to
read-only across all scopes. With reusable-workflow permission scoping,
this caps the called workflow's `security-events: write` /
`id-token: write` declarations, blocking scorecard SARIF upload.
Manifests as startup_failure with no logs.

30 consecutive startup_failures on main since 2026-05-30. Canonical
shape per feedback_scorecard_wrapper_caller_permissions.md:
workflow-level `contents: read` + job-level write scopes.

Fan-out planned for downstream wrappers if green here.
…spatch

Working hypothesis on persistent startup_failure: the
`branch_protection_rule:` trigger may be the parse-time rejection
cause (no repo-level branch protection rule resource → parse error
during workflow ingestion). Dropping it as the next test.

Adding `workflow_dispatch:` so a manual trigger is available for
debugging without committing.

Previous attempt (fc7abf5): scoped permissions to contents:read —
no effect on startup_failure. Reverting that change of permissions
would be ergonomically counter-canonical, so leaving as-is.
Records today's 3 merged PRs, 4 in-flight campaigns, and the 3-layer
licence auto-PR hardening. NO SPDX/LICENSE edits.

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… prose) (#350)

## Summary

Implements the hybrid licensing for `consent-aware-http` per the
2026-06-02 owner directive (memory:
`feedback_consent_aware_http_hybrid_licensing.md`).

This is a follow-on to standards#344/#345 which left
`consent-aware-http/` excluded pending design.

## Hybrid licensing model

| Aspect | License | Rationale |
|---|---|---|
| **Source files** (`.zig`, `.yml`, `.a2ml`, Mustfile, etc.) | `MPL-2.0`
| Estate sole-owner default; standards parent's AGPL does NOT inherit
here |
| **Prose / spec / docs** (`.adoc`, `.md`) | `CC-BY-4.0` |
IETF-compatible; aligns with how standards bodies license specs |
| **In-text reference** | `PMPL-2.0-or-later` | Spec text REFERENCES
PMPL-2.0-or-later for cultural/ethical/post-quantum framing. NOT applied
as SPDX. |
| **LICENSE file** | `MPL-2.0` (canonical) | Code is the operative
source-level license; CC-BY-4.0 docs are handled via per-file SPDX |

## Scope (39 files + LICENSE)

**10 prose files** flipped `PMPL-1.0-or-later` → `CC-BY-4.0`:
- `consent-aware-http/SECURITY.md`
- `consent-aware-http/GOVERNANCE.adoc`
- `consent-aware-http/ROADMAP.adoc`
- `consent-aware-http/MAINTAINERS.adoc`
- `consent-aware-http/RSR_OUTLINE.adoc`
- `consent-aware-http/.migration/PYTHON_TO_RUST_AFFINESCRIPT.adoc`
- `consent-aware-http/PALIMPSEST.adoc`
- `consent-aware-http/CONTRIBUTING.adoc`
- `consent-aware-http/SCOPE.adoc`
- `consent-aware-http/CHANGELOG.adoc`

**29 source/infra files** flipped `PMPL-1.0-or-later` → `MPL-2.0`:
- 3 `.zig` source files (ffi/zig/)
- 14 `.yml` workflows (.github/workflows/)
- 6 `.a2ml` manifests (.machine_readable/6a2/)
- 2 Mustfile + 1 Dustfile + 2 .gitattributes/.gitignore + 1
.github/FUNDING.yml

**1 LICENSE replacement**: `consent-aware-http/LICENSE` → canonical
MPL-2.0 text (was PMPL-1.0-or-later).

## Why draft

Hybrid model is a first-of-kind shape; owner sight before merge. Test
plan below.

## Test plan

- [ ] CI green (no new SPDX violations)
- [ ] CC-BY-4.0 on prose verifiable: `grep -rl 'SPDX-License-Identifier:
CC-BY-4.0' consent-aware-http/` returns 10 files
- [ ] MPL-2.0 on source/infra verifiable: `grep -rl
'SPDX-License-Identifier: MPL-2.0$' consent-aware-http/` returns 28+
files
- [ ] LICENSE file is canonical MPL-2.0
- [ ] Confirm spec text body in `drafts/*.xml` references
PMPL-2.0-or-later (no SPDX applied — that's intentional)

## Related

- standards#344/#345 — left consent-aware-http excluded pending this
design
- docs/LICENSE-POLICY.md (standards#349) — captures the hybrid model in
the canonical estate policy doc
- Memory: `feedback_consent_aware_http_hybrid_licensing.md`

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-or-later (Phase 2) (#345)

## Summary

Phase 2 of the standards PMPL→AGPL-3.0-or-later sweep. Companion to #344
(Phase 1).

This PR covers the **7 standards-local sub-projects** that have their
own PMPL-1.0-or-later LICENSE files. LICENSE+SPDX flipped together to
align with standards parent's AGPL-3.0-or-later (per
[[standards_agpl_intentional]] memory; standards is category 3,
son-shared).

## Why standards-local (not standalones)

Verified via `gh api repos/hyperpolymath/<name>` that none of these 7
sub-projects exist as standalone GitHub repos — they're standards-local
sub-specifications.

## Scope (2,724 files)

**7 subdir LICENSE files replaced** (PMPL-1.0-or-later →
AGPL-3.0-or-later canonical text from standards root):
- `a2ml/` — 1,171 source SPDX
- `k9-svc/` — 1,160 source SPDX
- `rhodium-standard-repositories/` — 122
- `0-ai-gatekeeper-protocol/` — 107
- `lol/` — 105
- `axel-protocol/` — 49
- `outreach/` — 10

**2,717 source files** flipped `PMPL-1.0-or-later` →
`AGPL-3.0-or-later`.

## Explicitly EXCLUDED (still)

- **`avow-protocol/`** (90) — check-in copy of
`hyperpolymath/avow-protocol` standalone
- **`consent-aware-http/`** (39) — special hybrid licensing per owner
directive 2026-06-02 (MPL-2.0 source + CC-BY-4.0 spec +
PMPL-2.0-or-later reference). Phase 3.

## Pattern this PR follows

- `hyperpolymath/developer-ecosystem#106` (Phase 4 LICENSE+SPDX shape)
- **First time** the destination is AGPL not MPL

## Verification

```sh
for d in a2ml k9-svc rhodium-standard-repositories 0-ai-gatekeeper-protocol lol axel-protocol outreach; do head -1 "$d/LICENSE"; done
# all return: SPDX-License-Identifier: AGPL-3.0-or-later

grep -rl 'SPDX-License-Identifier: PMPL-1.0-or-later' a2ml k9-svc rhodium-standard-repositories 0-ai-gatekeeper-protocol lol axel-protocol outreach
# returns: 0 files
```

## Why draft

LICENSE replacements + first-of-kind AGPL destination; owner sight
before merge.

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… SARIF + gitleaks unblock) (#352)

## Summary

Two reusable workflows consume third-party actions that need GitHub-API
permissions the reusables didn't grant. Reusable workflow permission
blocks OVERRIDE the caller's, so adding perms at every consumer wrapper
is a no-op — **the fix must live here at source**.

This unblocks SARIF upload + gitleaks PR scan across **every estate
consumer** of these reusables.

## Reproducing failures (before this PR)

From `.git-private-farm#69` runs (verified Jun 02 18:34 UTC):

### hypatia SARIF upload
```
hypatia.sarif written: 48 result(s).
Run github/codeql-action/upload-sarif@...
  sarif_file: hypatia.sarif
Validating hypatia.sarif
Adding fingerprints to SARIF file.
##[error]Resource not accessible by integration - GET /actions/runs/...
```

The scan + SARIF generation **succeed**. The upload-sarif step then
calls `GET /repos/{owner}/{repo}/actions/runs/{run_id}` to attach the
blob and fails because `actions: read` is not granted.

### gitleaks ScanPullRequest
```
[hyperpolymath] is an individual user. No license key is required.
gitleaks version: 8.24.3
Gitleaks restored from cache
RequestError [HttpError]: Resource not accessible by integration
    at ... ScanPullRequest ...
```

The gitleaks binary scan **succeeds**. The post-scan `ScanPullRequest`
step calls additional API endpoints (PR-files, workflow-run metadata, PR
comment post) and fails because `pull-requests: write` + `actions: read`
are not granted.

## Changes

### `hypatia-scan-reusable.yml` — workflow-level

```yaml
permissions:
  contents: read
  security-events: write
  pull-requests: write
+ actions: read    # NEW — for upload-sarif's GET /actions/runs/{id}
```

Single-job workflow, so workflow-level is the right scope.

### `secret-scanner-reusable.yml` — gitleaks job-level only

The other jobs (`trufflehog`, `rust-secrets`, `shell-secrets`) only need
`contents: read`. Adding wider perms at workflow level would over-grant.
Gitleaks gets a job-level block instead:

```yaml
gitleaks:
+ permissions:
+   contents: read
+   pull-requests: write   # NEW — for PR comment post
+   actions: read          # NEW — for PR-files / workflow-run API calls
  steps: ...
```

## Why this is safe

Both new grants are **read-only** (`actions: read`) or **scoped to PRs
only** (`pull-requests: write`). They match GitHub's documented
permission requirements for these specific third-party actions:

- `codeql-action/upload-sarif` docs explicitly require `actions: read`
when calling from a wrapper.
- `gitleaks-action` v2 docs require `pull-requests: write` for PR
commenting + `actions: read` for the new PR-files API.

No new write capability beyond PR-comment posting, which already had to
be granted somewhere (incorrectly assumed it'd inherit from the caller).

## Blast radius

- `hypatia-scan-reusable.yml`: ~estate-wide consumer of Hypatia security
scan.
- `secret-scanner-reusable.yml`: 281 estate deployments per the
reusable's own header comment.

All consumers will see the fix on their next run via SHA-bump
propagation (which is exactly the cascade the 3-system propagation track
was designed for — `.git-private-farm#66` + `gitbot-fleet#249` +
`hypatia#419`).

## Test plan

- [ ] After merge: rerun `.git-private-farm#69` checks; both SARIF +
gitleaks transition to GREEN.
- [ ] Propagation cascade fires (or manual SHA bump if propagation not
yet live), and other estate consumers green up too.

## Related

- hyperpolymath/.git-private-farm#69 — local fixes that hit this
upstream wall
- hyperpolymath/.git-private-farm#66, #68 — 3-system propagation cascade
(this PR's merge SHA will be the first real propagation candidate)
- hyperpolymath/hypatia#419 — detection rule
- hyperpolymath/gitbot-fleet#249 — actuation script

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…#344)

## Summary

First in a per-subdir series for standards PMPL→**AGPL-3.0-or-later**
source-SPDX alignment.

**Note the direction**: standards is category 3 (son-shared per
[[standards-agpl-intentional]]), so source SPDX flips to
`AGPL-3.0-or-later`, **not** MPL-2.0 (which is the sole-owner default
for repos like dev-ecosystem and neurophone).

## Repo state confirmed

- Root LICENSE: AGPL-3.0-or-later ✓
- Source SPDX: 3,553 files carry `PMPL-1.0-or-later` from legacy
carve-out era
- consent-aware-http subdir has its own special hybrid (MPL-2.0 source +
CC-BY-4.0 spec + PMPL-2.0-or-later reference) — EXCLUDED from this PR

## Phase 1 scope (this PR)

**700 files** flipped `PMPL-1.0-or-later` → `AGPL-3.0-or-later`:

| Area | Files |
|---|---|
| Repo root | 28 |
| `docs/` | 319 |
| `.machine_readable/` | 57 |
| ~30 small subdirs with no own LICENSE (meta-a2ml,
session-management-standards, agentic-a2ml, anchor-a2ml,
k9-coordination-protocol, standards-update, scripts, state-a2ml,
ecosystem-a2ml, playbook-a2ml, neurosym-a2ml,
toolchain-readiness-grades, overlay-protocol, a2ml-templates,
.verisimdb, inline-annotations, hooks, launcher, contractiles,
adoption-readiness-grades, panll-panels, hypatia-rules,
foundations-readiness-grades, component-readiness-grades,
publication-pre-flight, ensaid-config, ai-instruction, tasks, standards,
release-pre-flight, tools, testing-and-benchmarking, .meta,
immaculate-guide, .github, accessibility) | ~296 |

## Explicitly EXCLUDED

| Path | Reason | Files |
|---|---|---|
| `a2ml/` | Own PMPL LICENSE — Phase 2 (LICENSE+SPDX to AGPL combined) |
1,171 |
| `k9-svc/` | Own PMPL LICENSE — Phase 2 | 1,160 |
| `rhodium-standard-repositories/` | Own PMPL LICENSE — Phase 2 | 122 |
| `0-ai-gatekeeper-protocol/` | Own PMPL LICENSE — Phase 2 | 107 |
| `lol/` | Own PMPL LICENSE — Phase 2 | 105 |
| `avow-protocol/` | Own PMPL LICENSE + check-in copy of standalone
`hyperpolymath/avow-protocol` — skip (fix in standalone) | 90 |
| `axel-protocol/` | Own PMPL LICENSE — Phase 2 | 49 |
| `consent-aware-http/` | **Special hybrid** licensing (MPL-2.0 src +
CC-BY-4.0 spec + PMPL-2.0-or-later ref) per owner directive 2026-06-02 |
39 |
| `outreach/` | Own LICENSE — Phase 2 review | 10 |

## Pattern this PR follows

- `hyperpolymath/neurophone#102` for SPDX-flip mechanics
- `hyperpolymath/developer-ecosystem#103/#105` for per-subdir scoping
- **First time** the destination is AGPL not MPL — be aware

## Verification

```sh
grep -rl 'SPDX-License-Identifier: PMPL-1.0-or-later' <phase-1-paths>
# returns: 0 files
```

## Why draft

License sweep + first-of-kind AGPL destination; owner sight before
merge.

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…icy (#347)

## Summary

Estate-wide **no hand-authored JavaScript (source)** rule plus its
warn-first CI enforcement.

- `docs/NO-JAVASCRIPT-SOURCE-POLICY.adoc` — canonical statement:
estate-authored logic is AffineScript→typed-wasm or Rust+Zig→wasm;
hand-authored `.js/.jsx/.mjs/.cjs/.ts/.tsx` is not an accepted
destination. Tightens the earlier "no *unnecessary* JS" stance
(standards#254).
- `.github/workflows/no-js-scan.yml` — **warn-first / non-blocking**
companion that reports the hand-authored JS/TS surface to the run
summary. Excludes generated (`*.res.js`, `*.res.mjs`, `lib/{js,es6,bs}`,
`out`, `dist`, `.deno`, `generated/`), vendored (`node_modules`,
`deps`), and declaration (`*.d.ts`) files.

**Relationship to existing enforcement:** this defers to hypatia
`cicd_rules/javascript_detected` as the authoritative hard-block — it
does not override or duplicate it. hypatia blocks *new* JS in
non-carve-out paths; this scan surfaces the *full existing* surface for
migration visibility.

Surface reported in this repo: **29** files.

## Notes
- Warn-only: cannot fail the build. Flips to blocking per-repo, by owner
decision, once a repo reaches zero.
- Companion workflow also added to `burble` (14) and `gossamer` (0).
`paint-type` pending write access (the `hyperpolymath` credential is
read-only there).

Draft for review.

https://claude.ai/code/session_01CS2BLBL22WTTjmc1UmEGa2

---
_Generated by [Claude
Code](https://claude.ai/code/session_01CS2BLBL22WTTjmc1UmEGa2)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
#349)

New docs/LICENSE-POLICY.md captures the canonical 5-way estate license
classification per the 2026-06-02 owner directive, references the
25-repo initial sweep (~14k files), and points at the hypatia governance
recipe (hypatia#423) that closes the automation loop going forward.

Standards is the right home for this doc since the policy is
estate-wide.

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…abled (#353)

## Summary

The hypatia-scan reusable's \`Upload SARIF\` step hard-fails when the
consumer repo has code scanning disabled (private repo without Advanced
Security, or any repo with the feature admin-disabled). That's a
legitimate consumer-side config choice, not a regression.

This adds a \`cs-probe\` step that queries \`/code-scanning/alerts\`
(continue-on-error so the probe itself never blocks) and gates the
upload step on the probe's verdict.

## Reproducer

[.git-private-farm#69 run
26843343488](https://github.com/hyperpolymath/.git-private-farm/actions/runs/26843343488):

\`\`\`
hypatia.sarif written: 48 result(s).
Run github/codeql-action/upload-sarif@...
  sarif_file: hypatia.sarif
Validating hypatia.sarif
##[error]Code scanning is not enabled for this repository.
       Please enable code scanning in the repository settings.
\`\`\`

The scan + SARIF conversion both succeed; the \`actions: read\` perm I
added in #352 correctly grants the upload its scope; the upload only
fails because the **feature itself** is not enabled on the consumer
repo.

## Preserved guarantees

Per the existing design comment (post-#35):

- ✅ Fork PRs still skip (token read-only) — unchanged.
- ✅ Genuine permission regression still hard-fails loud (the probe
checks only whether the feature is enabled, not whether the upload would
otherwise succeed).
- ✅ Malformed SARIF / API outage still hard-fails loud — same reason.
- ✅ Hypatia findings still land as a build artifact even when SARIF
upload is skipped (the upload-artifact step is unaffected).

The probe is **fail-open**: if the API call errors for any reason (rate
limit, transient outage), \`enabled\` ends unset (no \`enabled=true\` in
the output), upload is skipped. Loud-red regressions remain loud — the
probe just adds a graceful skip for the specific case where the feature
is administratively unavailable.

## Test plan

- [ ] .git-private-farm#69 re-run picks up new reusable SHA → SARIF step
skips with notice instead of hard-fail.
- [ ] Public estate consumers (where code scanning IS enabled by
default) still publish SARIF normally.
- [ ] Fork PRs still skip via the unchanged second clause of the
\`if:\`.

## Blast radius

Same as #352 — all estate consumers of \`hypatia-scan-reusable.yml\`.
The change is fail-open and additive: existing green paths stay green;
previously-red paths that were red BECAUSE of disabled-feature now go
green.

## Related

- #352 — added the perms; this completes the resilience
- .git-private-farm#69 — first consumer hitting the disabled-feature
path

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## What

Sets **standards'** top-level `LICENSE` to **MPL-2.0** (owner-directed
2026-06-02). The file previously declared `AGPL-3.0-or-later` with a
body that didn't match any licence template.

## Scope — LICENSE file only (no SPDX sweep)

`standards` is a **deliberately multi-licensed** repo —
`PMPL-1.0-or-later` dominates its spec/template content (3644 files),
alongside MPL-2.0, MIT, AGPL, Palimpsest-0.4, and CC-BY-SA. This PR
changes **only the top-level `LICENSE` file**; **per-file
`SPDX-License-Identifier` headers are intentionally left untouched** (no
bulk SPDX sweep, per the estate no-sweep mandate). The repo's mixed
per-file licensing is preserved exactly as-is.

Verified locally: `check-licence-consistency.sh` → **`[OK] Licence
consistency check passed`** (standards has no root build manifest, so
the gate validates the `LICENSE` SPDX + body alone; both now resolve to
MPL-2.0).

---
_Generated by [Claude
Code](https://claude.ai/code/session_01GsJX13UjwiBk9hkddqvYMh)_

Co-authored-by: Claude <noreply@anthropic.com>
## What this does

Turns the ~7,000-file standards monorepo into something an agent or
human can read as **one coherent thing** _or_ jump straight to exactly
what they need — and wires it into **live drift-detection automation**
so documentation rot becomes a detected, routed finding instead of
something noticed 60 days later.

Built on a fresh inventory (103 top-level entries, 7,026 tracked files,
28 spec homes verified to exist).

## ⚠️ OWNER REVIEW REQUIRED — read first

Commit **`f805bdc`** is isolated and contains the **only**
licence-touching changes: it corrects human-facing **doc badges/prose**
that asserted `PMPL-1.0-or-later` to **`MPL-2.0`**, matching the actual
`LICENSE` file (set owner-directed in #354). This is a
documentation-accuracy fix, **not** a relicensing.

- **No `LICENSE` file and no SPDX header is edited** — those stay
owner-only / Manual-Only per `.claude/CLAUDE.md`.
- Drop this one commit if you disagree; the rest stands alone.
- Files: `README.adoc` (badge + Licensing bullet + structure line + `==
License`; also dropped the "Philosophy: Palimpsest" badge since this is
not a Palimpsest carve-out repo), `ROADMAP.adoc`,
`QUICKSTART-MAINTAINER.adoc`, `PALIMPSEST.adoc` (added a NOTE that the
doc describes PMPL generally and that **this** repo is MPL-2.0).

The other commits only **remove** now-false `PMPL-1.0` claims (replaced
with neutral "see LICENSE" / Manual-Only wording) — they assert no
identifier.

## The two front doors

| Audience | Canonical entry |
|---|---|
| Human | `README.adoc` — now opens with a **"Start Here"** + **"if you
want X, go here"** routing table |
| Agent | `0-AI-MANIFEST.a2ml` — rewritten from a generic template into
the real machine entry, with routing + registry pointer + real
invariants |

Every other "what is this repo" doc is now a thin pointer back to these
two.

## The verifiable registry (Task 3)

- **`.machine_readable/REGISTRY.a2ml`** — generated index of **28
specs** across 6 streams; each `[[spec]]` has `home`, `canonical_doc`,
and a content-addressed **`source_hash`** (`sha256` over `git ls-files
-s <home>`).
- **`scripts/build-registry.sh`** — the generator (honest by
construction: only emits homes that exist; deterministic; idempotent).
`just registry` / `just registry-check`.
- **`REGISTRY.adoc`** — prose on the registry, how `source_hash` catches
drift, and the router.

## Drift becomes a detected, routed finding (Task 3)

```
file tree + STATE.a2ml ─► build-registry.sh ─► REGISTRY.a2ml ─► TOPOLOGY.md
                                ▲                     │
                                │                     ▼
              registry-verify.yml (CI)        HYP-S006 registry-staleness
              (fails build on drift)          emits doc.drift → hybrid router
```

- **`.github/workflows/registry-verify.yml`** — in-repo half: fails the
build on registry/topology drift.
- **`hypatia-rules/registry-staleness.a2ml` (HYP-S006)** — estate half:
recomputes hashes, emits `doc.drift`. Its `@router` defaults to
`auto_execute` (regenerate) but **hard-caps any licence/SPDX-overlapping
drift to `:review`**, honouring the Manual-Only guardrail and
`license_finding_strategy/0`.

## Confirmed drift fixed (Task 4)

- `EXPLAINME.adoc` → thin stub: drops the `ReScript`-as-Primary line
(banned 2026-04-30) and the **dead** `groove-protocol/` +
`palimpsest-license/` local links (both confirmed absent); defers the
spec inventory to the registry.
- `llm-warmup-{dev,user}.md` were **byte-identical** → now role-specific
stubs.
- `QUICKSTART-{DEV,USER,MAINTAINER}.adoc` — all `{{PLACEHOLDER}}`
markers filled (USER re-framed for a specs repo, not an app install).
- Doc badges → owner-review commit above.

## TOPOLOGY now derived (Task 5)

`TOPOLOGY.md` was hand-frozen at `2026-04-04` (80% overall while
integration read 0%). It is now **generated** from the registry +
`STATE.a2ml` — it can't freeze. Its existing `AGPL-3.0-or-later` SPDX
header is **preserved** (not touched).

## REORGANIZATION-PLAN.md superseded (Task 6)

Marked **SUPERSEDED** with a banner: its premise (move content out to
separate repos) predates the 2026-02-08 monorepo consolidation;
discoverability/drift are now handled by the registry + automation.

## Notes for the reviewer

- **New-file SPDX**: new/generated files use `AGPL-3.0-or-later` to
match the repo's current per-file SPDX convention (Phase 1/2 sweeps
#344/#345) and to **preserve** TOPOLOGY.md's existing header. Note the
`LICENSE` file is MPL-2.0 — the LICENSE-vs-per-file-SPDX classification
is an owner-only question I did **not** resolve.
- `just registry-check` is green; output is deterministic (commit
`83e83a6` removed a volatile timestamp that would have spuriously
tripped CI).

## Out of scope (untouched)

A2ML/K9 spec internals (Stream 1); AffineScript spec text (Stream 2);
any `LICENSE`/SPDX edits (owner-only — flagged, not fixed).

https://claude.ai/code/session_011xv3VLrqeXkpjXxUojKz82

---
_Generated by [Claude
Code](https://claude.ai/code/session_011xv3VLrqeXkpjXxUojKz82)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
## What

Adds `docs/reorg/STREAM-PROMPTS.adoc` — a durable capture of the plan
for untangling this repo, split into **three independent work streams**,
each as a self-contained prompt that can be handed to a separate
session:

1. **A2ML + K9-SVC foundation (+ 6a2)** — the cross-cutting substrate
between attestation (A2ML) and validation (K9). Run first; it produces
the base record vocabulary and verifiable registry the others depend on.
2. **AffineScript standards placement** (`.affine`/`.affex`/`.affmap`) —
source-of-truth in the AffineScript repo, registry pointers only here.
3. **Front door + de-sprawl** — one canonical human + machine entry
point, drift fixes, and hypatia/router automation wiring.

## Settled principles recorded

- **SSOT + verifiable registry** — one home per spec; no duplicated
normative text; hypatia verifies pointer `source_hash` for staleness.
- **SemVer-for-specs + era label** — additive changes are minor bumps;
"v2" is a roadmap heading only; one-`SPEC.adoc` + `archive/` +
`VERSIONS.adoc` lineage convention.
- **A2ML and K9-SVC are independent foundations** — CodeCite (broad
citations) and ProofTrace (specialist obligation-linking) are standalone
*consumers*; consumer profiles live in consumer repos.
- 2026-06-03 owner decisions: A2ML v1.1 = profiles + base vocab +
citations (obligations → v1.2); `@profile(id)` in-document; 6a2 → A2ML
profiles; K9 → 1.0.0 stable with capabilities, enforceable leash,
pedigree restructure, A2ML+JSON receipts.

## Notes

- Documentation only — no spec or licence/SPDX changes.
- Stream 3 deliberately contains **no** licence/SPDX editing, only
owner-reviewed doc-badge correction, per the manual-only licence
guardrail.

Draft: this is the planning artifact; the streams themselves are
follow-on work.

https://claude.ai/code/session_01AmPXB2dA2wCcabo8BXwS28

---
_Generated by [Claude
Code](https://claude.ai/code/session_01AmPXB2dA2wCcabo8BXwS28)_

Co-authored-by: Claude <noreply@anthropic.com>
…shing) and K9-SVC 1.0 hardening (#358)

## Foundational layer: A2ML + K9-SVC

The substrate between attestation (A2ML) and validation (K9). A2ML and
K9-SVC are
**independent foundations that name no consumer**; CodeCite/ProofTrace
stay as
standalone consumers in their own repos. **All 13 tasks landed.**

### Owner decision captured
- **K9 Hunt leash** requires **all five** preconditions, **always**
(signature +
policy + sandbox + dry-run + capability grant) — no configurable subset.

### A2ML (`a2ml/`)
1. ✅ **Lineage cleanup** — prior specs frozen under `archive/` (v0
draft, v1.0.0)
with NOT-NORMATIVE banners; `SPEC.adoc` is the single normative spec
(**v1.1.0**);
`VERSIONS.adoc` is the lineage SSOT; README reconciled "Draft v0.6.0" →
   "Stable v1.1.0". Licence prose untouched (flag-only).
2. ✅ **Profile mechanism** — `@profile`/`@profile-def`, offline
deterministic
   resolution, SSOT + hash-pinned registry (SPEC §8/§11).
3. ✅ **Base record vocabulary** `@record` — the anti-desync primitive
(SPEC §7).
4. ✅ **Citation primitives** — inert without a citation profile (SPEC
§10).
5. ✅ **Canonical hash form** (sha256); signing reserved & inert (SPEC
§9).
6. ✅ **Idris2 core** — `BaseVocab.idr` + `Profiles.idr`, decidable
checks, `%default total`.

### 6a2 (`.machine_readable/`)
7. ✅ Seven profile definitions `a2ml/state … a2ml/anchor` + verifiable
`REGISTRY.a2ml`.
8. ✅ `@profile` on all seven 6a2 files; hypatia rule **HYP-S006
profile-drift-detector** (FLAG-ONLY).

### K9-SVC (`k9-svc/`) — finishes alpha → **1.0.0 STABLE**
9. ✅ **Capability model** (`capabilities.ncl`): closed core enum +
reserved `x-` namespace; default-deny.
10. ✅ **Leash modes normative** (`leash.ncl`): Kennel/Yard/Hunt;
`authorize_hunt` = all five, always.
11. ✅ **Pedigree restructure** (`pedigree.ncl`): 7 sections incl. new
`recovery_recipe` + `docs_rationale`.
12. ✅ **Receipt schema** (`receipt/`): canonical `a2ml/k9-receipt`
profile + lossless JSON projection + worked example.
13. ✅ **Soft A2ML cross-ref** (`docs_rationale.a2ml_ref`);
must/just/nickel vs must/trust/dust/intend kept distinct.

### CI notes (for reviewers)
- **governance / Trusted-base** failure was mine (a `partial`); fixed by
making
`sectionTitlesOf` total — eliminated the escape hatch (verified locally,
gate exits 0).
- **Idris2 a2ml/AVOW** failures were **pre-existing shared infra** in
  `echidna-verify.yml` (deprecated `actions/cache` pin + an interactive
idris2-pack bootstrap that hit EOF + wrong PATH). Both fail identically
on AVOW
(which this PR never touches). Fixed: bumped the cache pin to a SHA
already
trusted in-repo, fed the pack prompt its default, corrected PATH. This
also
  wires the new v1.1 a2ml core into the type-check.
- **Hypatia security scan** (222 findings) are all `workflow_audit`
items
(`unpinned_action`, `missing_timeout_minutes`) on workflow files this PR
does
  not modify — pre-existing/estate-wide, not introduced here.

### Note on SPDX
New files match their directory's existing SPDX convention
(`AGPL-3.0-or-later`).
Pre-existing licence drift in `a2ml/` prose (README/spec say
`PMPL-1.0-or-later`
while headers say `AGPL-3.0-or-later`) is **flagged, not touched**, per
the
manual-only licence policy.

🤖 Draft.

https://claude.ai/code/session_01XZhw6Fq27eoeyEB4LR3a2c

---------

Co-authored-by: Claude <noreply@anthropic.com>
hyperpolymath and others added 24 commits July 28, 2026 14:22
Replace duplicate workflow implementations with calls to root reusable
workflows (*-reusable.yml). Remove instant-sync.yml duplicates.

- codeql.yml: use ../../../.github/workflows/codeql-reusable.yml
- governance.yml: use ../../../.github/workflows/governance-reusable.yml
- hypatia-scan.yml: use ../../../.github/workflows/hypatia-scan-reusable.yml
- mirror.yml: use ../../../.github/workflows/mirror-reusable.yml
- scorecard.yml: use ../../../.github/workflows/scorecard-reusable.yml
- scorecard-enforcer.yml: use ../../../.github/workflows/scorecard-reusable.yml
- secret-scanner.yml: use ../../../.github/workflows/secret-scanner-reusable.yml

Part of estate-wide CI/CD deduplication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Replace duplicate workflow implementations with calls to root reusable
workflows (*-reusable.yml) in:
- axel-protocol/
- consent-aware-http/
- lol/
- meta-a2ml/
- rhodium-standard-repositories/satellites/palimpsest-license/

Fix relative paths from ../ to ../../ for depth-1 directories.
Remove instant-sync.yml duplicates.

Part of estate-wide CI/CD deduplication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Replace duplicate workflow implementations with calls to root reusable
workflows (*-reusable.yml) in all rhodium-standard-repositories/satellites/ directories:
- cccp/ (depth 2)
- cccp/satellites/nextgen-languages/ (depth 3)
- cccp/satellites/nextgen-languages/7-tentacles/ (depth 4)
- cccp/satellites/php-aegis/ (depth 3)
- cccp/satellites/sanctify-php/ (depth 3)
- consent-aware-http/ (depth 2)
- ECOSYSTEM.scm/ (depth 2)
- META.scm/ (depth 2)
- mustfile/ (depth 2)
- palimpsest-license/ (depth 2)
- robot-repo-automaton/ (depth 2)
- rsr-certifier/ (depth 2)
- rsr-deployer/ (depth 2)
- state.scm/ (depth 2)
- well-known-ecosystem/ (depth 2)

Remove instant-sync.yml duplicates.
Remove codeql-analysis.yml duplicates.

Part of estate-wide CI/CD deduplication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
…kflows

Fix relative paths from ../ to ../../ for depth-1 directories:
- a2ml/.github/workflows/
- rhodium-standard-repositories/.github/workflows/

Remove instant-sync.yml duplicates.

Part of estate-wide CI/CD deduplication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Fix relative paths from ../ to ../../ for depth-1 directory:
- k9-svc/.github/workflows/

Part of estate-wide CI/CD deduplication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Delete duplicate instant-sync.yml files from all subdirectories.
The root .github/workflows/instant-sync.yml is the canonical one.

Removed from:
- 0-ai-gatekeeper-protocol/ (3 files)
- a2ml/ (3 files)
- k9-svc/ (6 files)

Part of estate-wide CI/CD deduplication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Fix relative paths from ../ to ../../ for depth-1 directory:
- 0-ai-gatekeeper-protocol/.github/workflows/

Part of estate-wide CI/CD deduplication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
…allers

Issue #527: governance-reusable.yml requires actions: read permission (added
in commit 0ced540), but all caller wrappers only granted contents: read,
causing startup_failures with zero jobs.

Fix: Add 'actions: read' permission to all 37 governance.yml wrapper files
across the estate.

Affected directories:
- 0-ai-gatekeeper-protocol/ (3 files)
- a2ml/ (6 files)
- axel-protocol/
- consent-aware-http/
- k9-svc/ (6 files)
- lol/
- meta-a2ml/
- rhodium-standard-repositories/ (15 files)

Part of estate-wide CI/CD deduplication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Issue #520: scorecard.yml template violates the estate's own Scorecard/SARIF policy
which requires OSSF Scorecard to run on every PR head commit when uploading to
Code Scanning.

Fix: Add pull_request trigger, concurrency, actions: read permission, and
secrets: inherit to all scorecard.yml wrapper files across the estate.

Updated 20 files in:
- 0-ai-gatekeeper-protocol/ (3 files)
- a2ml/ (6 files)
- consent-aware-http/
- k9-svc/ (6 files)
- lol/
- rhodium-standard-repositories/ (4 files)

Part of estate-wide CI/CD deduplication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Issue #516: Hypatia: setup-beam pin cannot map ImageOS=ubuntu24

Update erlef/setup-beam from 54075bcc5e249e4758d363f27d099f55d843f124
to 8736e9244717f9207464c14c6051b71d22253f60 (latest main) in:
- .github/workflows/hypatia-scan-reusable.yml
- .github/workflows/elixir-ci-reusable.yml

The old pin predates ubuntu24 support. ubuntu-latest now resolves to Ubuntu 24.04,
which sets ImageOS=ubuntu24, causing setup-beam to fail with:
  'Tried to map a target OS from env. variable ImageOS (got ubuntu24), but failed.'

The new commit includes ubuntu24 mapping, allowing Hypatia scanner to run on
all callers using ubuntu-latest runners.

Part of estate-wide CI/CD deduplication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Issue #505: governance-reusable: two jobs cannot fail

The 'Code quality + docs' job had several checks that could never fail:
- Check file permissions: used '|| true'
- Check TODO/FIXME: used '|| echo'
- Check for large files: used '|| echo'

Fix: Remove the fail-safe operators, add 'continue-on-error: true' to each
step, and add advisory comments explaining these are informational only and
repos can opt into blocking locally.

The 'Guix primary / Nix fallback policy' job was already fixed in dbfd661.
The trufflehog step was already removed in a previous commit.

Now all jobs in governance-reusable.yml have genuine failure paths.

Part of estate-wide CI/CD deduplication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
…(Issue #486)

- Add allowlist-preflight job that validates all uses: in caller workflows
  against the canonical allowlist
- Create scripts/check-actions-policy.sh wrapper script
- Uses sparse checkout to fetch only allowlist + scripts from standards
- Runs with only actions/checkout (github-owned) so it cannot startup-fail

This implements Issue #486: Wire allowlist preflight into governance gate.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
…adoc files (Issue #506)

- Fix contradictory license guidance in 11 AI-CONVENTIONS.adoc files
- Change AGPL-3.0-or-later to MPL-2.0 for source file SPDX identifiers
- Change PMPL-1.0-or-later to MPL-2.0 (PMPL only applies to palimpsest repos)
- Aligns with LICENCE-POLICY.adoc Rule 1: MPL-2.0 for code, CC-BY-SA-4.0 for docs

This addresses Issue #506: License normalization sweeper AGPL exceptions.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
…NA submission (#554)

Clears the last in-repo blocker to the **IANA media-type submission**.

## What I found

`a2ml/IANA-MEDIA-TYPE-APPLICATION.md` is a **complete, 259-line RFC 6838
vendor-tree application** for `application/vnd.a2ml` (rev 2, 2026-04-03,
*"Status: Draft — ready for submission"*). Its own checklist already
ticks *fields reviewed*, *spec links accessible*, *no naming conflict*,
and *ASAM A2L (`application/A2L`) distinction clarified*. The only
unticked items are **submit the form → monitor review → record the
assigned type**.

So the registration isn't months of work — it's **an owner action** (the
IANA web form needs applicant identity). But the repo contradicted its
own application in four places:

| name | uses | status |
|---|---|---|
| `application/vnd.a2ml` | 27 | ✅ the application doc's name |
| `text/a2ml` | 5 | ❌ incl. the **normative SPEC** |
| `application/vnd.a2ml+text` | 3 | ❌ `+text` is not a registered
structured-syntax suffix (RFC 6838 §4.2.8) |
| `application/a2ml` | 1 | ❌ standards-tree name — would need IETF
review, not the vendor tree |

A submission contradicted by its own normative spec invites
expert-review pushback, so this reconciles all four to the application
doc's name.

## Deliberately **not** touched
- `a2ml/archive/SPEC-v1.0.0.adoc` (×2) — frozen historical record; the
old name is *correct* there.
- `a2ml/RECORD-DIALECT-SPEC.adoc` §14 — it knowingly documents the
inconsistency and defers resolution to maintainers. Worth a small
editorial update **once IANA assigns the type**.

## Verification
`build-registry.sh --check` ✅ and `build-scorecards.sh --check --strict`
✅ locally. `REGISTRY.a2ml` regenerated because `SPEC.adoc` is
registry-tracked — which also clears the registry drift currently red on
main.

## ⚠️ Related risk for K9 (not fixed here)
K9's **dominant** name is `application/vnd.k9+nickel` (41 uses vs 11
bare `application/vnd.k9`). `+nickel` also does not appear in IANA's
Structured Syntax Suffix registry. **Verify before submitting K9** — if
unregistered, register bare `application/vnd.k9` and keep `+nickel` as
documentation, or pursue a separate suffix registration (slow; depends
on upstream Nickel).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…r (Issue #496)

- Delete stapeln.toml, contractile.just (stale generated output)
- Delete audit-contractiles.sh
- Delete SECURITY_TRAINING_SUMMARY.md
- Delete confusingly-nested standards/ subdir
- Move files to proper locations:
  - standards/automation/K9-AUTOMATION-SPEC.a2ml → automation/
  - standards/interop/CRG-TRG-RSR-MAPPING.a2ml → interop/
  - standards/language-testing-standards.md → docs/
  - standards/affinescript-testing-guide.md → docs/
  - standards/julia-testing-tools-guide.md → docs/
  - standards/templates/ → templates/

Partial completion of Issue #496 (carve-out 7/9).

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
…d PORT-REGISTRY.md (Issue #495)

- Move adoption-readiness-grades/AUDIT-FINDINGS-2026-05-28.adoc to docs/archive/
- Move publication-pre-flight/ESTATE-AUDIT-BASELINE-2026-03-30.adoc to docs/archive/
- Replace SATELLITES.a2ml with deprecation notice (retired per #479)
- Replace PORT-REGISTRY.md with deprecation notice (migrating to verisim-data)

Partial completion of Issue #495 (carve-out 6/9).

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
- Add scripts/check-implementation-inside-canon.sh: Detector for implementation files
  in canon directories (triggers on Cargo.toml, deno.json, Containerfile, CNAME, etc.)
- Add scripts/auto-archive-session-detritus.sh: Auto-archiver for session detritus
  files (COMPLETE reports, SESSION_SUMMARY, DEPLOYMENT-SUCCESS, etc.)

These scripts prevent recurrence of implementation creep and session detritus
accumulation per Issue #498 (After-eviction hygiene).

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
…g .ipkg (#555)

## The problem

`SPEC.adoc` §3.1 says: *"The **normative** Idris2 model lives in
`src/A2ML/` … **the source files are authoritative**."*

It did not type-check — and **nothing ever checked it**:
- **zero `.ipkg` files** anywhere under `a2ml/`, so there was no build
target;
- **no CI workflow** invokes the `core-tests` Justfile recipe (that
recipe is honest — it `exit 1`s when `idris2` is absent — but nothing
calls it).

So the authoritative definition of A2ML has been unverified. Given the
family is about to be registered with IANA and three dialects must agree
through this core, that is the foundation to fix first.

## What this PR does

**Adds `a2ml/a2ml-core.ipkg`** so the claim is machine-checkable:
`idris2 --typecheck a2ml-core.ipkg`. The ipkg target is deliberate —
per-file `idris2 --check` exits 0 when an imported module is merely
*missing*, which is a fake gate (an estate-wide lesson).

**Fixes `A2ML.Proofs`, which failed outright.** All four are genuine
proofs — **no `postulate`, no `believe_me`**:

1. `import Data.List.Quantifiers` — `All` was used but never imported,
so `uniqueAppendDisjoint`'s signature failed to elaborate ("No type
declaration for…").
2. **`elemAppend` was referenced twice but defined nowhere** and
imported from nowhere. Replaced with two lemmas proved by induction on
the `Elem` witness — `elemAppendLeft` (membership survives appending on
the right) and `elemAppendSplit` (membership in a concatenation is
membership in one side or the other). Both verified against Idris2
0.7.0.
3. `|>` is not an Idris2 operator; the intent was to weaken an `Elem`
across an append — exactly `elemAppendLeft`.
4. `validatedHasUniqueIds` / `validatedHasResolvedRefs` referenced the
argument by name in their own signatures *before binding it*, and
projected `ids`/`refs`/`uniqueProof`, which **three** record types share
(`UniqueDoc`, `ResolvedDoc`, `ValidatedDoc`). Bound the argument;
qualified the projections.

**Verified locally** with idris2 0.7.0: `A2ML.Proofs` now type-checks (0
errors, down from a hard failure). `TypedCore` and `Surface` type-check
too — Idris2 only proceeds to build `A2ML.Parser` once its dependencies
succeed.

## What remains — and why no CI gate here

`A2ML.Parser` still fails with **16 errors**: 7 unification failures, 6
totality failures (under `%default total`), an undefined `<|>`, and a
use of the private `TypedCore.collectIds`.

I have **deliberately not added a CI gate in this PR** — it would be red
on arrival, and landing a red required check would block the queue. The
gate should land together with the parser repair, tracked separately.
This PR is a strict improvement: the package manifest now exists and the
proof module is sound.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… tolerated (#557)

**Owner ruling, 2026-07-28:** *"nix flakes are deprecated and to be
thrown from the estate, we are only doing guix now… you can get rid of
them and references to them now or opportunistically as you think is
best."*

The canon already said *"Guix primary; NO Nix mirror"* (2026-05-18), but
**three places in this repo still read as though a flake were merely
discouraged** — and one actively tells you to keep it. A maintainer
following the current text would retain the flake and allowlist it. This
fixes the words, not the logic.

## What changed

**`spec/LANGUAGE-POLICY.adoc` §Package Management** — adds the hardened
paragraph: Nix is *removed*, not deprecated-but-tolerated, and removal
is a **standing opportunistic instruction** — strip it whenever you're
in a repo for any reason, including the *references* (direnv `use
flake`, `nix-shell` recipes, Dependabot's `nix` ecosystem,
package-manager detection branches, `.gitignore`/`.gitattributes`,
docs), not just the file.

It also records the measured caveat: **~25% of the estate's `guix.scm`
files are scaffold stubs, wrong-project, or `{{PROJECT_NAME}}`
placeholders**, so the *presence* of `guix.scm` is not evidence of
packaging.

**`scripts/check-package-policy.sh`** — the failure guidance led with
*"Do NOT simply delete the flake"*, which now reads as permission to
keep it. Rewritten to lead with removal **while keeping the real
engineering point that motivated it**: don't leave the repo unpackaged —
make Guix real (or fill the `Containerfile`, which is Podman-verifiable
where Guix isn't installable) *in the same change*. Explicitly rules out
allowlisting the flake.

**`.github/workflows/governance-reusable.yml`** — job renamed `Guix
primary / Nix fallback policy` → **`Guix packaging policy (Nix
retired)`**. There is no Nix fallback tier any more and the name was
teaching the opposite of the rule.

## Rename safety — checked, not assumed

A job rename changes the check-run name. A ruleset requiring the *old*
context would become a **phantom required check that never reports**,
blocking every merge — the known `--admin` trap.

I queried the rulesets on `standards`, `trope-checker`, `hermeneia` and
`hypatia`: the only required governance context is `governance /
Validate Hypatia Baseline`. **Nothing requires the Guix job.** Safe.

## Verified by running it

| case | result |
|---|---|
| Nix-only repo, past retirement date | `exit 1`, new guidance printed |
| repo with `guix.scm` | `exit 0`, *"Guix … detected (primary)"* |

`bash -n` clean; `governance-reusable.yml` still parses as YAML.

**No behavioural change to the policy logic** — the decision procedure,
grace-window variables and sealed-container detection are untouched.
This changes what the estate is *told*, plus one job label.

## Companion PR

`trope-checker`
[#47](hyperpolymath/trope-checker#47) is the
worked example: flake removed, the fake `guix-nix-policy.yml` deleted,
and ten config/script/doc references de-Nixed. Its root-shape gate went
FAIL → PASS with 0 failing checks.

## Scope note

61 other repos still carry a root `flake.nix` and 34 still carry the
fake `guix-nix-policy.yml`. Per the ruling those are to be handled
opportunistically; this PR makes the policy say so.

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

## The gap

The governance linter's `Check SHA-pinned actions` step verifies a pin's
**shape** (`@` + 40 hex). It cannot verify the SHA **exists** — a
fabricated 40-hex string passes it.

That is not theoretical. Measured across the estate on 2026-07-28:

| | |
|---|---|
| Unique `(action, SHA)` pins | **613** |
| **Unresolvable** | **112 (18%)** |
| — real repo, invented SHA | 80 |
| — action repo itself is gone | 32 (7 actions) |
| Committed workflow files affected | **876** |
| Repo roots affected | **~310** |

**Why it stayed invisible:** Actions resolves a `uses:` ref only at
*run* time, and an unresolvable ref produces **no check run at all** —
not a red one. `gh pr checks` shows nothing, the board reads green, and
the job never ran. A repo can be "fully green" with its security
scanning entirely absent.

Full report: `dev-notes/estate-unresolvable-action-pins-2026-07-28.md`.

## The change

- New `scripts/check-action-pins-resolve.sh` — dedupes `(repo, sha)`
pairs from the caller's workflows and asks the GitHub API whether each
resolves.
- Wired into the `workflow-lint` job, using the established idiom from
the allowlist preflight above it (sparse-checkout standards → copy
script to `$RUNNER_TEMP` → `rm -rf` the checkout *before* scanning, so
the standards tree is never part of the caller's workspace).

### Failure semantics (deliberate)

**HARD FAIL** only on a *determinate negative* — GitHub answered and the
answer was "does not exist". The script distinguishes `SHA-NOT-FOUND`
(repin it) from `REPO-NOT-FOUND` (the action is gone — vendor it, per
hyperpolymath/tangle#84).

**Does NOT fail** on indeterminate answers (rate limit, 5xx, network).
Those say nothing about a pin, and failing on them would turn any GitHub
incident into an estate-wide red treadmill — the exact trap
`check-workflow-staleness.sh` documents. They are instead counted and
reported **loudly** as `UNVERIFIED`. A fail-open that announces itself
is not a fake gate; a fail-open that hides is.

Rate limiting is not expected to bite: `GITHUB_TOKEN` allows 1,000
req/hr/repo and only *unique* pairs are queried (largest estate repo is
well under 100).

## Verification

Tested against three real repos:

| Repo | Result |
|---|---|
| `tangle` | 9/9 resolve → **exit 0** ✅ |
| `0patch-lsa-sentinel` | catches phantom
`github/codeql-action@29b1f65c` → **exit 1** ✅ |
| `aerie` | catches both dead `a2ml-validate-action` +
`k9-validate-action` → **exit 1** ✅ |

`standards`' own 21 pins all resolve, so this repo passes its own new
gate.

YAML re-parsed (11 jobs preserved, step order correct); script passes
`bash -n` and `shellcheck -S warning` clean.

## Propagation caveat

Consumers pin `governance-reusable.yml` by SHA, so this step only starts
running for a consumer once it re-pins to a standards SHA at or after
this merge (`scripts/propagate-workflow-pins.sh` / the staleness gate
drive that). The *script* is always fetched from `main`, so its logic
stays current without a re-pin — but the step itself needs the newer
workflow.

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

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…branch (#559)

## Urgent follow-up to #558

#558 merged while the pin-gate's standards checkout was still
temporarily pointed at `feat/pin-existence-check`:

```yaml
repository: hyperpolymath/standards
ref: feat/pin-existence-check   # ← should be main
```

### Why that ref existed

A bootstrap problem. The gate fetches `check-action-pins-resolve.sh`
from standards, but while the PR was open the script did not yet exist
on `main` — so `cp` failed with *"No such file or directory"* and the
step could never be exercised. Temporarily pointing at the branch proved
the gate works end-to-end in real CI: **21 pins checked, all resolved, 5
seconds, no UNVERIFIED**. The revert back to `main` was pushed, but
landed *after* the merge.

### Why it must be fixed now

Every consumer's Governance run currently checks out a **feature
branch**. Deleting that branch — routine post-merge hygiene — breaks the
gate across the estate. The branch is deliberately still alive until
this merges.

The bootstrap problem is gone: the script is on `main` as of #558, so
`ref: main` now resolves correctly.

Verified: YAML re-parses with all 11 jobs, `ref = main`, zero remaining
references to the feature branch.

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

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…calation (#560)

## The problem

Five workflows on standards' `main` have been dead — **Rust CI, Elixir
CI, Deno CI, CodeQL, Scorecard** — each reporting `startup_failure` with
**zero jobs**. No logs, no red step, just an empty run, which is why
they persisted.

## Single root cause

A reusable workflow may **narrow** its caller's permissions but never
**widen** them. Requesting a permission the caller hasn't granted aborts
the run before any job starts.

| caller | granted | reusable requested | missing |
|---|---|---|---|
| `rust-ci` | `contents:read` | `+ actions:read` | `actions:read` |
| `elixir-ci` | `contents:read` | `+ actions:read` | `actions:read` |
| `deno-ci` | `contents:read` | `+ actions:read` | `actions:read` |
| `codeql` | `contents:read` | `+ actions:read, security-events:write` |
both |
| `scorecard` | `actions,contents:read` | `+ security-events:write,
id-token:write` | both |

## Two fixes, chosen per case

**rust / elixir / deno → narrow the reusable.** The top-level `actions:
read` is used by **no job**: all 8 jobs declare their own `contents:
read`, and nothing in these files downloads cross-workflow artifacts or
calls the Actions API (verified by grep). Removing it is least-privilege
*and* fixes every consumer at once **without touching ~150 wrapper
workflows** — a reusable that requests less is compatible with strictly
more callers.

**codeql / scorecard → widen the caller.** `security-events: write`
(SARIF upload, which branch protection depends on) and `id-token: write`
(Scorecard OIDC) are genuinely required. Only standards' own two
wrappers were widened.

## Verification

Machine-checked that every caller/reusable pair now satisfies the subset
rule, comparing the caller's grant against the union of the reusable's
top-level **and** every job block:

```
OK  rust-ci   -> rust-ci-reusable      OK  codeql    -> codeql-reusable
OK  elixir-ci -> elixir-ci-reusable    OK  scorecard -> scorecard-reusable
OK  deno-ci   -> deno-ci-reusable      ALL SUBSET-SAFE
```

Confirmed every job in the three narrowed reusables declares its own
`permissions:` (5/5, 2/2, 1/1), so nothing was relying on top-level
inheritance. All five files re-parse with job counts intact.

### Noted, not changed

Several other reusables (`mirror`, `readme-derive`, `hypatia-scan`) have
top-level permissions their jobs don't re-declare — but there the jobs
**inherit** the top level, so it is load-bearing, not dead weight. Left
alone deliberately. `scorecard-reusable`'s job block omits `contents:
read` entirely, which is worth a separate look.

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

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
guix.scm declared (name "squisher-corpus") — the squisher clobber, which
copied one package definition into many repos carrying the wrong project's
identity. Measured across 418 repos: 45 repos affected.

Fixes IDENTITY ONLY: name, synopsis, description, home-page and the header
comment. The (license ...) form is deliberately left untouched — the licence
drift (58 repos asserting PMPL) is a separate owner decision.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Answers gitar-bot's review comment on #555. The bot was RIGHT that the documented
command fails; its diagnosis was incomplete and its suggested remedy was to soften
the comment. Measured instead:

  idris2 --typecheck a2ml-core.ipkg  ->  exit 1, 16 errors  (Idris2 0.7.0)

Two things, not one:

1. CODE FIX. 2 of the 16 had a single root cause. strIndex : String -> Int -> Char
   is PARTIAL and returns a bare Char -- it cannot represent 'past the end'. peek
   and char pattern-matched its result as Just c / Nothing, so Char could never
   unify with Maybe ?_. Added a total, bounds-checked charAt : String -> Nat ->
   Maybe Char (ParserState.position is already a Nat, so the cast goes too).
   Verified: 16 -> 14 errors.

2. HONEST HEADER. The remaining 14 are real and are now stated in the file:
   7 totality, 5 unification, 1 undefined <|>, 1 private collectIds.

   More importantly: the header claimed this package makes SPEC.adoc §3.1
   'machine-checked' and pointed at 'the CI job that consumes this'. NO WORKFLOW
   IN THIS REPOSITORY INVOKES IT. The claim was decorative -- which is precisely
   the fake gate the very next paragraph of that header warns about.

   Stated plainly rather than quietly narrowing the modules list, because
   scoping the list to the modules that happen to pass would have made the
   command succeed while making the claim LESS true.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread a2ml/src/A2ML/Parser.idr
@gitar-bot

gitar-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown

Note

Automatic reviews are paused because your trial's included automatic processing has been used for this period. Upgrade now, or comment "Gitar review" to run a review anytime.
Learn more

Code Review 🚫 Blocked 1 resolved / 2 findings

Corrects a2ml peek/char parsing errors and updates the ipkg header, but the guix.scm license constructor is called with 2 of 3 required arguments and parseBlocks truncates documents at the first @directive.

🚨 Bug: guix.scm license constructor called with 2 of 3 required args

📄 guix.scm:17-18

((@@ (guix licenses) license) "PMPL-1.0-or-later" "https://...") invokes the low-level <license> record constructor, which is (license name uri comment) and requires three arguments. Passing only name and uri raises a wrong-number-of-arguments error, so guix shell -f guix.scm (the documented usage) fails to load the file. Add the missing comment argument, e.g. (license ((@@ (guix licenses) license) "PMPL-1.0-or-later" "https://github.com/hyperpolymath/palimpsest-license" "")).

Pass the required third `comment` argument to the license constructor.
(license ((@@ (guix licenses) license) "PMPL-1.0-or-later"
           "https://github.com/hyperpolymath/palimpsest-license" "")))
✅ 1 resolved
Bug: parseBlocks truncates document at first @directive

📄 a2ml/src/A2ML/Parser.idr:210-224 📄 a2ml/src/A2ML/Parser.idr:240-245
parseBlock returns pure Nothing for the Just '@' case, and parseBlocks treats a Nothing result as end-of-document, returning MkDoc acc. As a result any @directive block silently truncates parsing and discards the remainder of the document (including the @abstract and @refs blocks in exampleA2ML). Distinguish "no more input" from "produced no block" (e.g. have parseBlock signal EOF separately) so directives don't terminate the parse. Note this code does not yet type-check per the ipkg header, so this is latent behavior.

🤖 Prompt for agents
Code Review: Corrects a2ml peek/char parsing errors and updates the ipkg header, but the guix.scm license constructor is called with 2 of 3 required arguments and parseBlocks truncates documents at the first @directive.

1. 🚨 Bug: guix.scm license constructor called with 2 of 3 required args
   Files: guix.scm:17-18

   `((@@ (guix licenses) license) "PMPL-1.0-or-later" "https://...")` invokes the low-level `<license>` record constructor, which is `(license name uri comment)` and requires three arguments. Passing only name and uri raises a wrong-number-of-arguments error, so `guix shell -f guix.scm` (the documented usage) fails to load the file. Add the missing comment argument, e.g. `(license ((@@ (guix licenses) license) "PMPL-1.0-or-later" "https://github.com/hyperpolymath/palimpsest-license" ""))`.

   Fix (Pass the required third `comment` argument to the license constructor.):
   (license ((@@ (guix licenses) license) "PMPL-1.0-or-later"
              "https://github.com/hyperpolymath/palimpsest-license" "")))

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>
@hyperpolymath
hyperpolymath merged commit 3b65e7b into main Jul 29, 2026
23 of 26 checks passed
@hyperpolymath
hyperpolymath deleted the fix/a2ml-parser-charat-and-honest-ipkg branch July 29, 2026 05:43
@sonarqubecloud

Copy link
Copy Markdown

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.

2 participants