Skip to content

fix(ci): repoint standards callers; close the open review findings from #425 - #427

Merged
hyperpolymath merged 2 commits into
mainfrom
marina/eager-mendel-l8skln
Nov 10, 2026
Merged

hyperpolymath merged 2 commits into
mainfrom
marina/eager-mendel-l8skln

Conversation

@hyperpolymath

@hyperpolymath hyperpolymath commented Nov 10, 2026 •

Copy link
Copy Markdown
Owner

Summary

Two commits. The first one repairs CI. The second one closes the review findings that #425 left open when it merged.

1. CI: six workflows have failed at startup since 2026-10-26

Rust CI, Governance, Mirror, Hypatia, Secret Scanner and Scorecard each failed with zero jobs on every run since 3bdc7e4. The run name was the file path, which is the sign of a startup failure. So the Rust build and test gate did not run for #418, #421, #422 or #425.

Cause: hyperpolymath/standards moved to metadatastician/standards. GitHub does not follow the redirect for jobs.<id>.uses (standards#1442). The old pin 571cc734 also predates standards#1367, so the transfer playbook says to repin it.

  • All six callers now pin metadatastician/standards at be39f900 (main HEAD). At that commit, every uses: in the six reusables has a record in the standards actions.lock. I checked this from the parsed YAML.
  • actions.lock is relocked: the record has the new owner (owner_id 297579217, same repo_id), 7 records are added and 6 dead records are removed. scripts/check-lock-sync.sh passes with 0 dangling edges.
  • scorecard.yml: the job now grants actions: read, because the callee asks for it.
  • secret-scanner.yml: secrets: inherit is removed. The callee declares no secrets.
  • mirror.yml: secrets: inherit is replaced by the 10 named secrets that the callee declares.

2. Review findings left open on #425

#425 merged with 28 unresolved bot threads. Two CodeRabbit commits (8dadf82, 1ec49ee) landed minutes before the merge, and no Rust CI ran on them. Most threads were already fixed by those commits. I checked each one against main. These still reproduced and are fixed here:

  • Wasm match was always an i32 block. A pair destructuring whose body returns I64 passed check, but compile emitted invalid wasm. Reproduced, then fixed.
  • The bump pointer at mem[0] was never set, so the first heap cell was written over it. T(1, 2, 3) destructured to 167772701, not 321. This is the "nested pairs are wrong" item in the "known and open" list of No-False gate hardening, D0/D0b status sync, and the W0 wave (E0/E1 holes, probes, aLib conformer) #425. Fixed with one data segment. The new test fails without the fix.
  • Ownership section: a compound type with a linear component was emitted as Unrestricted. It is now Linear.
  • --debug wrote "mode": "linear" for every module. It now writes per-binding.
  • Dead code from the bot commit (clippy warning) is removed.
  • probe-battery.sh: it now requires GNU timeout, escalates to SIGKILL, and keeps the timeout verdict.
  • Docs: the Coproc.eph comments claimed that the I32 tag is widened to i64, which is false. The README run command is now marked historical.
  • Tests added for the requested items: 3-tuple projection, I64 destructuring, the value of a 3-field constructor, raw FFI under let, region-exit accounting, compound ownership kinds.

Not fixed here, deferred to rung E10 with a reason in each thread: typed extern in ephapax run, and the Coproc tag width. The language has no I64 literal or conversion yet.

Validation (local)

  • cargo test --workspace: 571 passed, 0 failed
  • cargo clippy --workspace --all-targets: 0 warnings; cargo fmt --check: clean
  • scripts/status-gate.sh --tests / --proofs: OK (568 tests, 0 admitted). TEST-NEEDS.adoc is updated from 554.
  • No-False gate self-test: 29/29. Probe battery: 57 SAME, 1 SKIP. Probe-battery self-test: 4/4.

Notes for the owner

  • Blocker: the repo Actions policy. On this PR's first push, the four standards callers that run on PRs (Rust CI, Governance, Secret Scanner, Hypatia) still fail with startup_failure and zero jobs. Before this change they failed earlier, as an unparsed file path. Now GitHub resolves the new coordinate and then refuses it at plan time. The transfer playbook (standards docs/compliance/repo-transfer-to-enterprise-playbook.adoc §4) describes that symptom for a caller on "selected actions". Please add metadatastician/standards/.github/workflows/*@* in Settings → Actions → General. Also check that the actions the reusables use are allowed: canon is standards config/settings/actions-allowlist.json. Or run scripts/widen-actions-allowlist.sh hyperpolymath/ephapax --apply from a standards checkout with admin access. Then re-run the failed runs. I cannot read or change that setting from this session, and the run page that gives the exact reason is not reachable from here.
  • The commits carry the session SSH signature, not your GPG key. They need a re-sign or a squash merge.
  • No formal/ file is changed.

Generated by Claude Code

Since 2026-10-26 every workflow that calls a standards reusable (Rust CI,
Governance, Mirror, Hypatia, Secret Scanner, Scorecard) has failed at
startup with zero jobs. hyperpolymath/standards moved to
metadatastician/standards, and GitHub does not follow the repository
redirect for `jobs.<id>.uses` (standards#1442). The old pin 571cc734
also predates standards#1367, so the transfer playbook says it cannot be
kept.

- All six callers now pin metadatastician/standards at be39f900 (main
  HEAD). At that commit every `uses:` in the six reusables has a record
  in standards' own actions.lock (checked from the parsed YAML).
- actions.lock: the standards record moves to the new owner (owner_id
  297579217, same repo_id) and lists the actions the six reusables use at
  be39f900. Seven records are added from standards' lock; six records
  that only the old pin used are removed. scripts/check-lock-sync.sh
  passes: transitively closed, 0 dangling edges.
- scorecard.yml: the job grants `actions: read`, which the callee asks
  for. Job-level permissions replace the top-level set.
- secret-scanner.yml: `secrets: inherit` is removed; the callee declares
  no secrets (standards#1108 6b).
- mirror.yml: `secrets: inherit` is replaced by the ten named secrets the
  callee declares.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0136P7ZnmBahbhfkFEP6ark4
PR #425 merged with 28 unresolved bot review threads, and two bot
commits landed minutes before the merge without CI (Rust CI was dead,
see the previous commit). Most threads were already fixed by those
commits; this change fixes the rest that still reproduce.

Code:
- wasm: `compile_match` opened every match block as `i32`. A pair
  destructuring whose body returns I64 (an extern call) type-checked but
  `compile` emitted invalid wasm. The block now takes the first arm's
  type, and `infer_expr_valtype` knows `Match`.
- wasm: the bump pointer at mem[0] was never initialised, so the first
  heap cell was allocated over it. Nested pairs and three-field
  constructors read back corrupt fields (`T(1, 2, 3)` gave 167772701,
  not 321). A data segment now sets it past the metadata and string data.
- wasm: `ty_to_ownership_kind` now maps a product, sum, tuple or list
  with a linear component to Linear, matching `Ty::is_linear`.
- wasm: `--debug` wrote `"mode": "linear"` for every module. It now
  writes `per-binding`, because discipline is per binding.
- interp: remove `find_ffi_symbol` and `value_to_i64_with_cstrings`,
  left unused when raw `__ffi` evaluation was removed (clippy warning).
- probe-battery.sh: require GNU timeout (BusyBox reports expiry as 143),
  escalate to SIGKILL 5 s after the deadline, and keep that as `timeout`.

Docs: Coproc.eph said the I32 capability tag is widened to the shim's
i64; nothing widens it. The comments now say so (fix is rung E10). The
README marks the `ephapax run -L` command as historical.

Tests: three-element tuple projection, the I64 pair destructuring, the
three-field constructor's runtime value, raw FFI under a `let`, region
exit accounting, and compound ownership kinds. TEST-NEEDS.adoc: 568.

Validation: cargo test --workspace 571 passed, 0 failed; clippy 0
warnings; fmt clean; status-gate --tests and --proofs OK; no-False gate
self-test 29/29; probe battery 57 SAME, 1 SKIP; probe-battery self-test
4/4.

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

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 53 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 9f0827ad-97c2-4cc0-b27a-acf8d6876642
Commits

Reviewing files that changed from the base of the PR and between ec425b0 and 591db60.

Files ignored due to path filters: 1

  • .github/workflows/actions.lock is excluded by !**/*.lock
Files selected for processing: 16

  • .github/workflows/governance.yml
  • .github/workflows/hypatia-scan.yml
  • .github/workflows/mirror.yml
  • .github/workflows/rust-ci.yml
  • .github/workflows/scorecard.yml
  • .github/workflows/secret-scanner.yml
  • TEST-NEEDS.adoc
  • scripts/probe-battery.sh
  • src/ephapax-cli/tests/fail_loud.rs
  • src/ephapax-cli/tests/linearity_holes.rs
  • src/ephapax-interp/src/lib.rs
  • src/ephapax-typing/src/lib.rs
  • src/ephapax-wasm/src/debug.rs
  • src/ephapax-wasm/src/lib.rs
  • stdlib/Coproc.eph
  • tools/coproc/README.adoc
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Share

@sonarqubecloud

Copy link
Copy Markdown

@hyperpolymath
hyperpolymath marked this pull request as ready for review November 10, 2026 11:13
@hyperpolymath
hyperpolymath enabled auto-merge (squash) November 10, 2026 11:13
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ❌ Failed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-10T11:16:01.075554Z 591db60 Draft marked ready
🔒 Security Review ❌ Failed 2026-11-10T11:13:19.751611Z
We couldn’t complete this review. Comment @codex security review to try again.
591db60 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

This security review couldn’t start because the paying account has exhausted its Codex allowance and has insufficient available credits. The payer can check their balance and add credits in the Codex usage dashboard, then try again. If you do not manage the paying account, contact this repository's admins.

Copy link
Copy Markdown
Owner Author

Blocker: a repo setting, not a code change. Auto-merge is waiting on four checks: Rust CI, Governance, Secret Scanner and Hypatia. Each one ends in startup_failure with zero jobs.

  • Before this PR, these runs failed as an unparsed file path, because GitHub cannot find the moved hyperpolymath/standards coordinate.
  • With this PR, GitHub parses the files and resolves metadatastician/standards, and then refuses the runs at plan time. The other five checks pass, including Lock Sync Gate and Status Gate.

The standards transfer playbook (§4) gives this symptom for a caller on "selected actions". To unblock:

  1. Settings → Actions → General: allow metadatastician/standards/.github/workflows/*@*. Also allow the actions the reusables use; canon is standards config/settings/actions-allowlist.json. Or run scripts/widen-actions-allowlist.sh hyperpolymath/ephapax --apply from a standards checkout with admin access.
  2. Re-run the four failed runs.

I cannot read the policy or the run page from this session. So this is the most likely cause, not a confirmed one. If the re-runs still fail, the run page states the exact reason. Please paste it here and I will fix the cause.


Generated by Claude Code

@hyperpolymath
hyperpolymath merged commit b1b2dd6 into main Nov 10, 2026
15 checks passed
@hyperpolymath
hyperpolymath deleted the marina/eager-mendel-l8skln branch November 10, 2026 12:30
hyperpolymath pushed a commit that referenced this pull request Nov 10, 2026
Conflicts:
- src/ephapax-wasm/src/lib.rs: both sides fixed the uninitialised bump
  pointer and the i32-only match block. Kept this branch's versions: they
  also set the region stack pointer and take the block type from the
  checker's type table.
- tools/coproc/README.adoc: kept the `--interp` flag and main's
  "historical" warning on that command.
- TEST-NEEDS.adoc: 590 all-target tests after the merge
  (status-gate --tests OK).

Validation: cargo test --workspace 593 passed, 0 failed; clippy 0
warnings; fmt clean; status-gate --proofs OK; lock sync OK; probe
battery 53 SAME, 5 SKIP (no wasmtime CLI here).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0136P7ZnmBahbhfkFEP6ark4
hyperpolymath added a commit that referenced this pull request Nov 10, 2026
…(E5) (#426)

## Summary

Rungs E3, E4 and E5 of the v2 plan
(`docs/reports/2026-11-04-v2-survey/EPHAPAX-V2-ARCHITECTURE-AND-PLAN.adoc`),
the first three rungs of the "a real program runs" level.

### E3: one front end (`ephapax-driver`)

A new crate, `src/ephapax-driver`, runs one pipeline: resolve imports,
parse (surface grammar, core-parser fallback), desugar, type-check, and
reject constructs that codegen cannot lower. `check`, `compile`, `run`,
the REPL, the LSP and the query engine all load programs through it.
Before, `check` had no import resolver, and the other tools used the v1
core parser only.

- The import resolver moves from the CLI into the driver.
- When both parsers reject a file, the driver reports the surface
parser's errors.
- An integer literal outside the I64 range is
`ParseError::IntegerOutOfRange` (it became `0`). `-9223372036854775808`
is one literal, `i64::MIN`.
- `import foo.bar` reaches `module foo/bar`, and the reverse. The module
index takes the `module` header from the parser, not from a line scan.
- **Module-qualified merge.** A program becomes one wasm module. When
two modules declare a function of the same name, the merge keeps both:
the root keeps its names, and the other function becomes
`<module>::<name>`. Each reference follows the function that the type
checker resolved it to. Before, the merge kept one function for both
modules, and the callers of the other one ran the wrong code with no
diagnostic.
- `src/ephapax-tools` stays out of the workspace; the reason is in
`Cargo.toml`.

### E4: `ephapax run` executes the wasm

`ephapax run` compiles the program and executes the module in-process
(wasmtime). It provides `env.print_i32`, `env.print_string` and the
`stdlib/Argv.eph` host imports, with the program path as `argv[0]`. The
entry point is the `main` of the root module. The interpreter is `run
--interp`; `-L` is rejected without it.
`tests/interp-known-failures.txt` lists the corpus files on which the
interpreter disagrees (1 file).

### E5: typed code generation

Codegen lowered every operator to i32 and guessed value types from
syntax. It now reads the type that the checker gave each expression.

- **Type table.** `Expr` gets an `ExprId` (not part of equality, `Debug`
or the serialised form). The checker records the type of every
expression. Codegen checks the module it is given and reads that table;
a program the checker rejects is a `CodegenError`.
- **Scalars.** Binary operators, comparisons and negation select i32,
i64, f32 or f64 instructions. `if`, `case`, `match` and `let` take the
type of their value.
- **Containers.** Pairs, sums, `copy`, tuples and lists store each
element at its own type and width. List indexing is bounds-checked.
- **Pair patterns.** A pair pattern loads each component at its own type
and offset, and a variable pattern binds a local of that type. This
covers a destructuring `let (a, b) = ...` and a constructor with several
fields.
- **Operators.** Float `%` is an exact `fmod` helper. `==` on strings
compares contents. `1.5f32` is an F32 literal.
- **Checker.** Ordering on a non-numeric type, and equality on a pair,
sum, list or function, are now type errors. The checker accepted both;
the two back ends then gave different answers.
- **Interpreter.** Integer arithmetic wraps, as the wasm does. `MIN /
-1` is an error; `MIN % -1` is 0.

### Defects fixed on the way

- **Allocator.** The bump pointer and the region stack pointer started
at 0, so the first allocation overwrote the bump pointer. This was the
cause of the wrong result for nested pairs.
- **`String.len`.** The runtime helper was declared with two parameters
but takes one, so every use gave an invalid module.
- **Surface parser.** It rejected every unary operator (`-x`, `!x`), and
`fst(e)` / `snd(e)`. A program that also used `data` or `match` then
failed.
- **Tuples.** `.0` and `.1` parsed as `fst` / `snd`, which the checker
rejects on a tuple of three or more.

## Results

| Check | Before | After |
|---|---|---|
| Corpus files that pass `check` (of 121) | 13 | 17 |
| Corpus files where `check` and `compile` disagree | 4 | 0 |
| `ephapax run p1.eph` | `ParseError` | prints `162` |
| Probes i64, s1, s6, t3 | `InvalidWasm` | compile and run |
| Probe battery rows at the plan target | 42 of 58 | 50 of 58 |
| `cargo test --workspace` (with `main` at #427 merged in) | 566 pass |
599 pass, 0 fail |

The 8 probe rows not at target all wait for E7 (generics, qualified
constructors).

## Gates

- `tests/driver_agreement.rs`: every entry point agrees with the driver
on all 121 corpus files (LSP twin in `ephapax-lsp`); the integer-literal
range on every command; `check` rejects what typed codegen cannot lower;
the query engine compiles the program that it checked.
- `tests/run_wasm.rs`: `run p1.eph` prints 162; three argument vectors;
interpreter and wasm agreement ratchet; a selective import; the entry
point; each module calls its own function of a shared name; pair
patterns bind each component at its type.
- `tests/typed_codegen_matrix.rs`: a generated type x operation matrix,
3255 cases, each run as wasm and in the interpreter: 0 disagreements, 31
cases with a pinned expected value. A second test passes each numeric
type through an extern parameter and result.

## Review findings

Codex and CodeRabbit raised 30 threads. All 30 are resolved (commits
f939dc2, 9b61a4d, 2beaac1, a3f559f, ce81f1b, d9a0221 and 8ba1b5e). Five
of them were regressions from this pull request: REPL declarations
checked in isolation, a selective import that failed in codegen, `check`
accepting what `compile` refused (a wide pattern, then a wide lambda),
and LSP analyses that could publish out of order or after a close.

3 threads are resolved by owner decision, with no change here:

- LSP: imports from unsaved buffers. Later, with the LSP rung (E11).
- LSP: a module-index cache. Later, with E11.
- Constructor visibility: one desugaring registry serves the whole
import graph, so `import dep(f)` also gives access to the constructors
of `dep`. Later, with E7.

3 findings had no thread (they were in a review body):

- Query engine: two equal load failures did not compare as equal, so a
failing program lost the recompute skip. Fixed in 0841afe.
- Query engine: `wasm` loaded a program with imports two times and could
compile a different snapshot than the one it checked. Fixed in 8ba1b5e.
- CLI: the `Error:` summary line of a type error uses the `Debug` form.
Not changed: `tests/eph_corpus_gate.rs` reads that form, and the
positioned line above it already uses the readable form.

## Not done

- **A tuple, constructor or literal pattern in a core `match` on a value
with an I64, F32 or F64 component.** These patterns still read i32
values, so `check`, `compile` and `run` refuse them with the same error.
Only core-syntax files reach them: the surface language lowers its
patterns to `case`, `if`, projections and pair patterns, which are
typed.
- **A lambda with an I64, F32 or F64 parameter or result.** Every
closure has the signature `(i32, i32) -> i32`, so `check`, `compile` and
`run` refuse it with the same error. Use a named function. The plan puts
the typed closure signature in E9.
- **A name that two modules declare, where at least one declares it as
an extern function.** An extern function cannot get a module-qualified
name: its name is the name of the host import. The driver refuses such a
program with an error that names both modules (owner decision). Two
modules may declare the same host import (same ABI, same signature).
- **aLib F64 re-binding** (the E6 widening that follows E5).
- **An argv fixture that prints the argument text.** An `.eph` program
cannot read bytes from a raw buffer yet.
- **A `fmt` entry point.** The CLI has no `fmt` command.

## Notes for the owner

- `TEST-NEEDS.adoc`: the documented all-target test count is 596.
- The four `wasm-run` probe baselines for i64, s1, s6 and t3 are
recorded from `ephapax run` (same engine). The wasmtime CLI was not
installed in this session.
- The interpreter cannot call a function of zero or several parameters
by name. This is not changed here.
- The interpreter reads a parameter that has the name of a top-level
function as that function (`fn shadow(helper: I32)` with a function
`helper`). The wasm path is correct. This is not changed here.
- A named function used as a value (`let h = g`, or a partial
application) passes `check`, and codegen then gives an invalid module
(`unknown table 0`), for 32-bit types too. `compile` and `run` refuse
the module with a validation error. This is not changed here; it belongs
with E9.
- `let (a, b, c) = (1, 2, 3)` is a type error, for 32-bit types too: the
pattern lowers to nested pairs, and a literal of three elements has a
tuple type. This is not changed here.
- `Codegen::compile_module_with_main` has no caller in this repository.
Its fallback is now `compile_program`.
- The commits carry the session SSH signature, not the owner GPG key.

## Validation (local, at 8ba1b5e)

- `cargo test --workspace`: 599 passed, 0 failed.
- `cargo fmt --all --check`: clean.
- `cargo clippy --workspace --all-targets`: no warnings.
- `scripts/status-gate.sh`: test count 596 matches.
- `scripts/probe-battery.sh`: 53 SAME, 5 SKIP (no wasmtime CLI), at
71a4e2b; the two later commits do not change the CLI results.
- No file under `formal/` is changed.

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

https://claude.ai/code/session_0136P7ZmKrYLDC4WHi2yt11u

---------

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants