Skip to content

feat(ipc): register every panel-backend command, add the event pump - #164

Merged
hyperpolymath merged 6 commits into
mainfrom
claude/admiring-meitner-8qkxac
Oct 27, 2026
Merged

hyperpolymath merged 6 commits into
mainfrom
claude/admiring-meitner-8qkxac

Conversation

@hyperpolymath

@hyperpolymath hyperpolymath commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Why

#157 added the IPC table (src-gossamer/src/ipc.rs) with only the 10 coprocessor commands as a pilot. The other panel-backend modules compiled and were tested, but none of their handlers could be called from the webview. That is docs/TECHNICAL_DEBT.adoc F1.

What

  • ipc.rs: the table now registers all 239 panel-backend commands, in 43 module groups. With the 36 commands main.rs registers itself, the desktop shell exposes 275. Each entry follows the pilot's rules:
    • async fn handlers run through block_on; sync handlers are called directly. Several sync handlers use reqwest::blocking, which must not run inside a runtime. I checked that no async fn handler uses blocking HTTP.
    • Option parameters are optional.
    • Struct parameters use struct_arg. It accepts a nested object, a flattened payload, or the struct sent as JSON text; the old frontend sent save_arrangement and save_session their struct as a string.
    • An AppHandle parameter is supplied by the backend.
    • Skipped: ums_cartridge::validate_level_data, a helper rather than a command.
  • Argument check against the old frontend. I compared every required argument with the pre-refactor: estate architectural upgrades #107 ReScript invoke() calls (git show 7a4f2cf^). The old frontend sent every one of them, so no further empty-means-default cases needed Option (the pilot's lib_path was the only one).
  • Event pump (main.rs). A g_timeout_add callback on the GTK main thread drains compat's event bus every 50 ms and hands each event to gossamer_emit. The callback only fires inside the event loop, while the window handle is live. gossamer_run frees the handle after the loop exits, so no tick can run on a freed handle. This is what makes ai_send_message_streaming chunks and watcher_start events reach the webview.
  • New test every_backend_command_is_registered. It scans every */commands.rs, *_live.rs and workspace/sysinfo.rs, up to the unit-test module, and fails if a public handler is reachable from neither the table nor main.rs. This covers the "command dispatch is total" item in PROOF-NEEDS.adoc.
  • Docs: updated the Cargo.toml header, EXPLAINME-new, TECHNICAL_DEBT (F1 and F2 marked resolved), the CHANGELOG, the PROOF-NEEDS "IPC dispatch is total" row, and the test counts in README, EXPLAINME-new and TEST-NEEDS (285 → 294).

Review follow-ups

Codex raised these, and all were real:

  • JSON-text struct arguments (6141af7): struct_arg now parses a string value as JSON before deserialising it.
  • Event pump (6141af7): the original background thread could call gossamer_emit on a freed handle. It is now the GTK-loop timer described above.
  • Missing multiplayer_monitor (c38063e): its six commands were not registered, and the test didn't notice. A test-only TEST_LOCK above the handlers made both the generator and the test stop reading the file there. The test now cuts at #[cfg(test)] mod tests. With the group removed, it fails and lists all six commands.

Checks

  • cargo fmt --all -- --check: clean.
  • cargo clippy --locked --all-targets -- -D warnings: clean.
  • cargo clippy --locked --features gossamer --all-targets -- -D warnings: clean. This was a type-check against a stub libgossamer. E2E's Rust job does the real Zig/GTK build, link and test; it passed on 6141af7.
  • cargo test --locked --lib: 294 passed. That includes required_arguments_are_enforced, which sends {} to every entry that has required arguments. All of them reject it before the handler runs, so the test has no side effects.

CI not caused by this PR

Rust CI, Governance, Hypatia and Secret Scanner fail at startup on this PR, and also on #162 and #163 (#163 has since merged); see the comment below.

Not tested

  • I haven't run the commands end to end in the desktop app. Most of them call local services (BoJ, VeriSimDB, TypeLL and others) that aren't running here.
  • The event pump hasn't been run in a live webview.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SJtjqoZaSQo7uBwvwVMA9G

The IPC table now covers all 233 panel-backend commands in 42 module
groups (the coprocessor pilot from #157 had 10). With the 36 that
main.rs registers itself, the desktop shell exposes 269 commands.

- Entries follow the pilot's rules: async handlers run through
  `block_on`, sync ones are called directly; `Option` parameters are
  optional, struct parameters use `struct_arg`, and `AppHandle` is
  supplied by the backend. Every required argument was checked against
  the pre-#107 frontend's `invoke()` calls, and the old frontend sent
  all of them.
- main.rs starts an event pump that drains `compat`'s event bus every
  50 ms and hands each event to `gossamer_emit`, which is thread-safe.
  This delivers AI streaming chunks and file-watcher events.
- New test `every_backend_command_is_registered` fails when a public
  handler in a command module is reachable from neither the table nor
  main.rs.
- Docs: Cargo.toml header, EXPLAINME-new, TECHNICAL_DEBT (F1 and F2
  resolved), CHANGELOG, and test counts (285 to 294).

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

coderabbitai Bot commented Oct 26, 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 23 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: 1e845cb3-3cae-42bd-afef-8f6d616caebb
Commits

Reviewing files that changed from the base of the PR and between bc601df and a1962a8.

Files selected for processing: 9
  • CHANGELOG.adoc
  • Cargo.toml
  • EXPLAINME-new.adoc
  • PROOF-NEEDS.adoc
  • README.adoc
  • TEST-NEEDS.adoc
  • docs/TECHNICAL_DEBT.adoc
  • src-gossamer/src/ipc.rs
  • src-gossamer/src/main.rs
  • 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

Comment @coderabbitai help to get the list of available commands.

@hyperpolymath
hyperpolymath marked this pull request as ready for review October 26, 2026 22:26
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

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

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-26T22:54:40.165978Z a1962a8 New commits
ℹ️ 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.

Copy link
Copy Markdown
Owner Author

Four checks are red on 095360a, but this PR didn't cause them: rust-ci.yml, governance.yml, hypatia-scan.yml and secret-scanner.yml all failed at startup. Each run lasted 0 s and ran no jobs, so no code was built or tested.

  • The same four workflows fail the same way on #162 (Dependabot, 26 Oct 12:46) and #163 (docs only).
  • They last passed on 23 Oct, on a Dependabot branch. Main's latest push run (1937c6b, 19 Oct) also passed.
  • This PR touches no workflow files.
  • All four call reusable workflows in hyperpolymath/standards. The 18 Oct startup failure ("invalid lockfile pin") had this same pattern and was fixed by repinning (ci: repin the standards reusables past the lockfile fix (standards#1271) #156).

I don't know of a fix yet, and the API doesn't return the startup error text. The error is shown on the run page: https://github.com/hyperpolymath/panll/actions/runs/40411215783. Re-running won't help, because the failure happens the same way every time, before any job starts.

Rust coverage for this PR comes from the checks that did run and passed: E2E "Rust Backend — Build + Check" (the real Zig/GTK build, link and cargo test --features gossamer), and Build Validation (cargo test --lib).


Generated by Claude Code

@hyperpolymath
hyperpolymath enabled auto-merge (squash) October 26, 2026 22:29

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 095360a3a3

ℹ️ About Codex in GitHub

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

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

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src-gossamer/src/ipc.rs Resolved
Comment thread src-gossamer/src/main.rs Resolved
claude and others added 3 commits October 26, 2026 22:35
Two findings from Codex review on #164:

- The old frontend sent `save_arrangement` and `save_session` their
  struct as JSON text (`{"arrangement": "<json>"}`), which `struct_arg`
  rejected as "invalid type: string". A string value is now parsed as
  JSON before deserialising.
- The event pump thread could call `gossamer_emit` with a freed handle:
  `gossamer_run` frees it when the event loop exits, before `run()`
  returns and before the stop flag was set. The pump is now a GLib
  timeout on the GTK main thread, which only fires inside the event loop
  while the handle is alive. The thread and the stop flag are gone.

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4b4f1075c6

ℹ️ About Codex in GitHub

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

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

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src-gossamer/src/ipc.rs Resolved
Comment thread src-gossamer/src/ipc.rs Resolved
claude and others added 2 commits October 26, 2026 22:47
…test-only items

Codex review on #164: multiplayer_monitor/commands.rs declares a
#[cfg(test)] TEST_LOCK above its six handlers. Both the generator that
built the table and every_backend_command_is_registered cut each file at
its first #[cfg(test)], so the six commands were never registered and
the test could not notice. The test now cuts at the unit-test module
(`#[cfg(test)]\nmod tests`), and the six commands are in the table;
with them removed the test lists all six. No other command file has a
test-only item above a handler.

Counts: 239 table commands, 275 in total.

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

Copy link
Copy Markdown

@coderabbitai

coderabbitai Bot commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Add Carrot credits or activate Agent usage billing to use Autofix

@hyperpolymath
hyperpolymath merged commit a81763a into main Oct 27, 2026
16 checks passed
@hyperpolymath
hyperpolymath deleted the claude/admiring-meitner-8qkxac branch October 27, 2026 00:06
hyperpolymath added a commit that referenced this pull request Nov 10, 2026
…te holes, totality and import cone, ledgers to PROOF-POLICY (#180)

Two subjects. The first commit moves PanLL onto the standards commit
that carries the fork pull request publisher
(metadatastician/standards#1408). The other two fix the proof ledgers
and the ABI gate against standards `3-practice/PROOF-POLICY.adoc` (§1.1,
§1.2, §4, §4.1, §5, §8), following a review of every proof in the
repository, and add one proof.

## 1. CI: repin standards, add the fork-PR publisher

- Every `metadatastician/standards` caller moves from `e064539` to
`9bdf864`, current standards `main`. The callers are governance,
hypatia-scan, scorecard, secret-scanner, mirror, the four
fork-governance lanes with `canon-ref`, and dogfood-gate's push-only K9
lane.
- That commit includes metadatastician/standards#1408 (the fork-PR
publisher), metadatastician/standards#1427 (the secret scanner fails
closed on missing history), metadatastician/standards#1417 and
metadatastician/standards#1418 (reviewer coverage), and
metadatastician/standards#1404 (panic-attack scope excludes).
- The callee changes add no input, secret or permission that the callers
don't already pass.
  - Rust CI stays on `412a703`.
- New `.github/workflows/fork-governance-publish.yml`, as in standards
ADOPTION.adoc §2:
- A `workflow_run` caller of `fork-governance-publish-reusable.yml` at
the same commit.
- `actions: read` and `pull-requests: write` are granted on the job
only.
- It takes effect once merged, because `workflow_run` runs the default
branch's copy.
- `actions.lock` was re-keyed with standards' own
`scripts/relock-standards-pin.sh` at `9bdf864`. The script refuses
unless every workflow's lock entries name exactly the refs it pins.
  - The nested `uses` of the standards record are unchanged.
- The publisher's only action, `download-artifact@9000827`, was already
recorded.
  - Dependency and workflow keys are in C-locale order.

## 2. Proofs: ledger conformance and gate hardening

The review found the Idris2 proofs sound as stated, and green on `main`:
Build Validation run 42408104327, job `panel-clades-abi`. It also found
the gaps below.

**Gate** (`panel-clades/scripts/check-abi.sh`)
- **Holes.** It now fails on a hole (`?name`); `idris2 --build` accepts
a module that has holes.
- **Totality.** It now fails on `partial` or `covering`, and on any
module without `%default total`. Idris2's default is `covering`, which
does not check termination.
- **Comments and strings.** The scan reads code only; comments and
string literals are set aside.
- **Import cone.** The typed-wasm modules that the proofs import (the
import cone, PROOF-POLICY §1.1) are now held to the same scan, and the
cone is printed. Before this, the kernel was trusted without any scan.
- **Tested both ways.** The real sources and the cone pass. Planted
holes, `partial`, `covering`, `believe_me`, `idris_crash` and a missing
`%default total` fail. The same words inside comments, strings and
nested block comments pass.

**`PROOF-NEEDS.adoc`**
- Every status is now a §5 token (`PROVEN`, `TESTED`, `OPEN`), with
notes kept separate.
- New "Policy class" section:
- All of PanLL's obligations are engineering obligations, so no Proof
Witness Grade applies (§8.1).
  - The grade-algebra laws are theory owned by resource-algebra.
  - It records where the Mathesis catalogue stands for this repository.
- A receipt for the last green run: checker and version, invocation,
import cone, result.
- New gaps found in review:
- `alignUpCorrect` holds by construction, while the rounding lower bound
that carries weight is unproved (`OPEN`).
  - `CABICompliant` certifies alignment only (`OPEN`).
- The `Nat` and `Bits32` tag tables were written separately and not tied
together. This one is now proved; see below.
- Kani (§4.1) is named for the `unsafe` and FFI seams.
- A §4 exception record for the TLA+ provenance model:
  - It has no receipt, because TLC is not run in CI.
  - Its invariant holds by construction.
  - It has no forging action.
  - The same record is summarised in the model's header.

**New proof** (`Types.idr`)
- `resultTagsAgree` and `cladeKindTagsAgree`: the `Bits32` C encoding of
each tag equals its `Nat` decidable-equality tag, so the two
hand-written tables cannot drift apart.
- Checked both ways. A planted drift is refused at `resultTagsAgree`
with "Mismatch between: 4 and 5". The drift encoded `NullPointer` as 5,
with `resultFromInt` changed to match so that both round-trip proofs
still passed.

**`docs/proof-debt.adoc`**
- Adds the two `unsafe` FFI calls in `main.rs`'s event pump that
#164 introduced.
- Records the new gate scope and names Kani as the verifier for the (d)
entries.

## Verification

- `relock-standards-pin.sh` at `9bdf864`: relocked.
- Lock key order checked with `LC_ALL=C sort -c`.
- Scan tests both ways, as listed above. The scripts pass `bash -n` and
`shellcheck -S warning`.
- Idris2 0.8.0 built locally from `15a3e4e`, the same commit CI builds:
`check-abi.sh` passes with 5 modules, 0 errors, 6 of 6 rejections and a
clean import cone of 5 typed-wasm modules.
- `idris2 --check` and `idris2 --build` both exit 0 on a module
containing `f = ?todo`. This confirms the hole gap the new scan closes.
- Not run here: standards' `check-lock-sync.sh`, because it needs Mike
Farah's `yq` v4, which this session could not install. The Governance
lane runs it on this PR.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.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.

2 participants