feat(formal): mechanize the four Wave-0 siblings (P-2, P-3, F-3, F-4)#626
Merged
Conversation
Turns the stated obligations in Siblings_Stated.v into actual proofs: each
new file builds a concrete model and proves the property, ending in a
`*_discharged : Siblings_Stated.<name> ... := <proof>` line that type-checks
the concrete proof against the stated obligation. All Coq/Rocq 8.18,
axiom-free (Print Assumptions: "Closed under the global context"), no Admitted.
P2_Progress.v — P-2 progress + preservation for a simply-typed first-order
calculus (nat/bool/add/if), small-step CBV, with the
standard canonical-forms development. Discharges
P2_progress + P2_preservation (ctx instantiated to unit).
P3_BorrowSound.v — P-3 for a one-resource borrow calculus: the precise
validity checker is sound, and REJECTS the #554 witness
[OBorrow; OMove; OUseRef] (matching lib/borrow.ml's
post-#554-fix behaviour). Discharges P3_borrow_soundness +
P3_rejects_554.
F3_PragmaDecidable.v — F-3: the alias table (parse_face_name) is a function,
and detection factors through the scanned region, so it
cannot depend on bytes past the pragma. Discharges
F3_alias_functional + F3_pragma_local.
F4_ErrorFaithful.v — F-4: the face renderer preserves an error's class and
referent, changing only vocabulary — no face can make
error X read as error Y. Discharges F4_error_faithful.
Scope is honest: these are small fragments, enough to discharge the obligation
and pin its meaning. Growing them toward the real language (functions/QTT for
P-2, the real borrow graph + Polonius #553 for P-3) is Wave 1.
justfile `check` + _CoqProject compile all eight files in dependency order and
assert no axioms (11 closure reports). .hypatia-ignore extends the
Coq-not-V-lang carve-out to the four new files. PROOF-NEEDS.adoc: P-2/P-3/F-3/F-4
moved to `partial` (mechanized model), Wave-0 row marked done; README + the
Siblings_Stated header point at the discharge files.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KPG9mEQXFyA3k7NWAzMNMr
🔍 Hypatia Security ScanFindings: 41 issues detected
View findings[
{
"reason": "Action denoland/setup-deno@v2 needs attention",
"type": "unpinned_action",
"file": "publish-jsr.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in instant-sync.yml",
"type": "secret_action_without_presence_gate",
"file": "instant-sync.yml",
"action": "peter-evans/repository-dispatch",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Shell execution -- validate input before passing to shell (1 occurrences, CWE-78)",
"type": "js_exec_sync",
"file": "/home/runner/work/affinescript/affinescript/packages/affinescript-cli/mod.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Shell execution -- validate input before passing to shell (2 occurrences, CWE-78)",
"type": "js_exec_sync",
"file": "/home/runner/work/affinescript/affinescript/packages/affine-vscode/mod.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Shell execution -- validate input before passing to shell (1 occurrences, CWE-78)",
"type": "js_exec_sync",
"file": "/home/runner/work/affinescript/affinescript/affinescript-vite/src/affine-plugin-improved.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "expect() in hot path (32 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/affinescript/affinescript/affinescriptiser/src/codegen/wasm_gen.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (29 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/affinescript/affinescript/affinescriptiser/src/codegen/affine_gen.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unsafe block -- requires SAFETY comment (2 occurrences, CWE-676)",
"type": "unsafe_block",
"file": "/home/runner/work/affinescript/affinescript/runtime/src/panic.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unsafe block -- requires SAFETY comment (1 occurrences, CWE-676)",
"type": "unsafe_block",
"file": "/home/runner/work/affinescript/affinescript/runtime/src/alloc.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unsafe block -- requires SAFETY comment (3 occurrences, CWE-676)",
"type": "unsafe_block",
"file": "/home/runner/work/affinescript/affinescript/runtime/src/ffi.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
added a commit
that referenced
this pull request
Jun 21, 2026
## Problem The merge box shows four **required** checks stuck at *"Expected — Waiting for status to be reported"*. This push confirmed it server-side: ``` - 4 of 4 required status checks are expected. ``` "Expected" is **not** a failure — it means a required context name was *never reported on the head commit*. Each of the four is produced by a different mechanism, and each can independently fail to report (proven against live PRs: affinescript #626, hypatia #517, gitbot-fleet #307): | Required context | Producer | Why it can sit "Expected" | |---|---|---| | `analyze (actions, none)` | `codeql.yml` job `analyze` | `pull_request:` was gated to `branches:[main,master]` → no run on other bases → check never created | | `hypatia / Hypatia Neurosymbolic Analysis` | `hypatia-scan.yml` reusable caller `hypatia` | same branch gate | | `Hypatia` | Hypatia **GitHub App** check | external; rides on the scan — absent on PRs where the scan didn't run (e.g. gitbot-fleet #307) | | `governance / Validate Hypatia baseline` | the **`standards` governance reusable** (job `governance` / "Validate Hypatia baseline") | this repo migrated off that reusable to a standalone `governance` job (#603/#604), which emits the context **`governance`** instead — so the pinned name is **orphaned and can never report** | Root cause (one line): **branch protection pins context strings that this repo only *conditionally* emits** — a renamed job, branch-filtered workflows, and an external app — and GitHub renders any required-but-unproduced context as a permanent "Expected", indistinguishable from a hang. ## What this PR changes (repo-side fix) 1. **`codeql.yml`** — drop `pull_request: branches:[main,master]`. The required `analyze (actions, none)` job now runs on PRs against **every** base. (`push:` unchanged.) 2. **`hypatia-scan.yml`** — same de-gate, so `hypatia / Hypatia Neurosymbolic Analysis` runs on every PR base (and the `Hypatia` app check rides along). 3. **`governance-baseline.yml` + `governance-baseline-impl.yml`** (new) — a **local reusable** whose caller job id `governance` + reusable job `Validate Hypatia baseline` re-emit the exact pinned context `governance / Validate Hypatia baseline`, on every PR. It is: - **additive** — the standalone `governance.yml` gate is untouched; the repo now emits both `governance` and `governance / Validate Hypatia baseline`; - **safe vs. the reasons #603/#604 left the reusable** — it's *local* (no `@main` cross-repo coupling) and declares **no** `concurrency:` in the reusable (avoids the BP008 startup-failure class); - **a real gate** — validates `.hypatia-baseline.json` with `jq` (no npm) when present; passes with a notice when absent (this repo's current state). ## Residuals that need branch-protection admin (cannot be done from repo files) - **`Hypatia` app check**: de-gating the scan is the best repo-side lever, but the app posting is ultimately external. If it still shows "Expected" on some PRs, either make it post unconditionally or **de-require** it. - **Pin reconciliation (the cleaner fix)**: the truly correct change is to repoint the pins to the names this repo actually emits — `governance / Validate Hypatia baseline` → `governance`, and confirm no *other* `governance / *` sub-checks (the reusable emits 8) are still pinned from the pre-#603/#604 era. The local-reusable bridge here exists only so the box can go green **without** that admin access; if you'd rather repoint the pin, this bridge can be dropped. ## Verification This PR's own run should now report all four contexts instead of leaving them "Expected"; `governance / Validate Hypatia baseline` is self-demonstrating (the new workflow runs on this PR). I'll confirm from the check-runs once they land. ## Estate note `codeql.yml` / `hypatia-scan.yml` carry the identical `branches:[main,master]` PR gate in `hypatia`, `gitbot-fleet`, and `.git-private-farm`; the same de-gate applies there. The `governance` divergence is **affinescript-only** — the other three still call the reusable and emit `governance / Validate Hypatia baseline` natively. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01UXXpaoiATzxcn3kW3eTM26 --- _Generated by [Claude Code](https://claude.ai/code/session_01UXXpaoiATzxcn3kW3eTM26)_ Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Turns the four stated Wave-0 siblings in
Siblings_Stated.vinto mechanized proofs. Each new file builds a concrete model, proves the property, and ends in a*_discharged : Siblings_Stated.<name> … := <proof>line that type-checks the concrete proof against the stated obligation. All Coq/Rocq 8.18, axiom-free (Print Assumptions→ "Closed under the global context"), noAdmitted.P2_Progress.vadd/if), small-step CBV, with canonical formsP3_BorrowSound.v[OBorrow; OMove; OUseRef]F3_PragmaDecidable.vF4_ErrorFaithful.vP3_BorrowSound.vmatcheslib/borrow.ml's post-#554-fix behaviour (per the newSOUNDNESS.adoc): the sound checker is exactly the one that now rejects use-after-move through a callee-returned borrow.Scope (honest)
These are small fragments — enough to discharge the obligation and pin its meaning, not the full language. Growing them is Wave 1: functions/binders/QTT for P-2, the real borrow graph + Polonius (#553) for P-3.
Wiring & docs
justfile check+_CoqProjectcompile all eight files in dependency order and assert no axioms — 11 closure reports..hypatia-ignoreextends the Coq-.v-isn't-V-lang carve-out to the four new files.PROOF-NEEDS.adoc: P-2/P-3/F-3/F-4 →partial(mechanized model); Wave-0 row marked done.README.adoc+ theSiblings_Statedheader point at the discharge files.Check
Verified locally: 8 files, 11 closure reports, zero axioms.
🤖 Generated with Claude Code
https://claude.ai/code/session_01KPG9mEQXFyA3k7NWAzMNMr
Generated by Claude Code