Skip to content

Commit e07a773

Browse files
feat: real proof gate + typell bridge (route δ opened for measurement) (#44)
## What Kategoria's 13 Idris 2 modules were genuinely verified — but nothing enforced it: `just test` was a TODO echo stub, no workflow ever ran `idris2`, and the repo's own metadata (`STATE.a2ml`, `TOPOLOGY.md`, README scorecard) misdescribed or understated the work. This PR makes the real work visible and enforced, then opens route δ by registering **typell** as its first measurement target. ## Changes - **Proof gate**: `scripts/check-idris2-proofs.sh` — hard-fails when `idris2` is absent (a gate that skips is not a gate), checks all 13 modules, rejects axiom smuggling (`postulate`/`believe_me`/`assert_total`/`%hint` outside comments). Verified 13/13 under Idris 2 **0.7.0** and **0.8.0**; negative-tested without the prover (exit 1). - **CI**: `.github/workflows/proof-gate.yml` — the first workflow that compiles this repo's substance, on every push/PR. - **Justfile**: `test`/`build` now run the gate. - **Dependabot**: drop 5 phantom ecosystems (no cargo/mix/npm/hex/pip manifests exist) that have been failing since 2026-07-14. - **De-drift**: TOPOLOGY.md documents the real layout (the `approach-1..5/` + `spec/` map never existed); ROADMAP route-α table matches measured reality (L8 ✓ via dependent-pair encoding; L4 = Type Classes; L10 wall stands); README Progress scorecard row α filled (9 ✓, L10 ✗); STATE.a2ml replaced (was RSR-template residue describing the *template repo*). - **Quarantine**: `src/interface/ffi` is uninstantiated template scaffold (`{{project}}` placeholders — cannot compile under any zig); documented, excluded from gates. Follow-up decision: instantiate for route δ's ABI or remove. - **Route δ bridge**: `routes/delta-aggregate/TYPELL-BRIDGE.adoc` — reconciles the **colliding L1–L10 hierarchies** (kategoria = language features; typell = safety properties; only L9 aligns), gives an evidence-backed enablement matrix against `typell-core`, and defines what flows each way. Companion typell PR adds the conformance suite + fixes typell's own (never-run, currently failing) Idris ABI proofs. ## Verification - `just proof-check` → `PASS=13 FAIL=0` (run under both prover versions) - Negative test: hiding `idris2` from PATH → exit 1 with FATAL message - Not touched: secret-scanner/gitleaks workflows (owned by the parallel security sweep) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 58decb0 commit e07a773

10 files changed

Lines changed: 381 additions & 142 deletions

File tree

.github/dependabot.yml

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
# SPDX-License-Identifier: MPL-2.0
2-
# Dependabot configuration for RSR-compliant repositories
3-
# Covers common ecosystems - remove unused ones for your project
2+
# Dependabot configuration for kategoria.
3+
#
4+
# This repo's code is Idris 2 (no package manifest Dependabot understands)
5+
# plus GitHub Actions workflows. Declaring ecosystems without manifests
6+
# (cargo/mix/npm/hex/pip from the RSR template) produced 5 standing
7+
# Dependabot failures on 2026-07-14 — only github-actions is real here.
48

59
version: 2
610
updates:
7-
# GitHub Actions - always include
811
- package-ecosystem: "github-actions"
912
directory: "/"
1013
schedule:
@@ -13,39 +16,3 @@ updates:
1316
actions:
1417
patterns:
1518
- "*"
16-
17-
# Rust/Cargo
18-
- package-ecosystem: "cargo"
19-
directory: "/"
20-
schedule:
21-
interval: "weekly"
22-
# `open-pull-requests-limit: 0` suppresses routine version-update PRs
23-
# while leaving Dependabot SECURITY PRs flowing. The previous
24-
# `ignore: "*" patch` rule also silenced security PRs under GitHub\'s
25-
# current Dependabot behaviour. See rsr-template-repo commit 78b050e
26-
# and 007-lang/audits/audit-dependabot-automation-gap-2026-04-17.md.
27-
open-pull-requests-limit: 0
28-
29-
# Elixir/Mix
30-
- package-ecosystem: "mix"
31-
directory: "/"
32-
schedule:
33-
interval: "weekly"
34-
35-
# Node.js/npm
36-
- package-ecosystem: "npm"
37-
directory: "/"
38-
schedule:
39-
interval: "weekly"
40-
41-
# Python/pip
42-
- package-ecosystem: "pip"
43-
directory: "/"
44-
schedule:
45-
interval: "weekly"
46-
47-
# Nix flakes
48-
- package-ecosystem: "nix"
49-
directory: "/"
50-
schedule:
51-
interval: "weekly"

.github/workflows/proof-gate.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# SPDX-License-Identifier: MPL-2.0
2+
# Proof Gate — type-checks the repo's real substance on every push and PR.
3+
#
4+
# This is the FIRST workflow in this repository that compiles the Idris 2
5+
# modules the project exists to produce. It hard-fails when the prover is
6+
# missing (scripts/check-idris2-proofs.sh refuses to skip).
7+
#
8+
# Verified locally under Idris 2 0.7.0 (system) and 0.8.0 (nixpkgs):
9+
# 13/13 modules PASS, axiom-smuggling scan clean.
10+
name: Proof Gate
11+
12+
on:
13+
push:
14+
branches: [main]
15+
pull_request:
16+
17+
permissions:
18+
contents: read
19+
20+
jobs:
21+
idris2-proofs:
22+
name: idris2 --check (13 modules)
23+
runs-on: ubuntu-latest
24+
timeout-minutes: 30
25+
steps:
26+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
27+
28+
- uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7
29+
30+
- name: Run proof gate
31+
run: nix shell nixpkgs#idris2 -c ./scripts/check-idris2-proofs.sh

.machine_readable/6a2/STATE.a2ml

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,61 @@
11
# SPDX-License-Identifier: MPL-2.0
22
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
33
#
4-
# STATE.a2ml — Project state checkpoint (META-TEMPLATE)
4+
# STATE.a2ml — Project state checkpoint for kategoria.
55
#
6-
# This is the STATE file for kategoria.
7-
# When consumed by a new project, replace {{PLACEHOLDER}} tokens
8-
# and customize sections below for the target project.
6+
# HISTORY NOTE: until 2026-07-21 this file was unedited RSR-template
7+
# residue describing the TEMPLATE repository ("95% complete, production,
8+
# maintenance"). Everything below is measured project state.
99

1010
[metadata]
1111
project = "kategoria"
12-
version = "0.2.0"
13-
last-updated = "2026-02-28"
12+
version = "0.1.0"
13+
last-updated = "2026-07-21"
1414
status = "active" # active | paused | archived
1515

1616
[project-context]
1717
name = "kategoria"
18-
purpose = "Canonical RSR-compliant repository template providing scaffolding for all hyperpolymath projects — including CI/CD, AI manifests, ABI/FFI standards, container ecosystem, and governance infrastructure."
19-
completion-percentage = 95
18+
purpose = "The Type Safety Challenge: five independent language-implementation routes (α Extend Idris 2, β Dyadic, γ Aspect, δ Aggregate, ε Clean Slate) exploring all 10 known levels of type safety. Named after Aristotle's Categories."
19+
completion-percentage = 25
2020

2121
[position]
22-
phase = "maintenance" # design | implementation | testing | maintenance | archived
23-
maturity = "production" # experimental | alpha | beta | production | lts
22+
phase = "implementation" # design | implementation | testing | maintenance | archived
23+
maturity = "alpha" # experimental | alpha | beta | production | lts
24+
25+
[verification]
26+
# Enforced by scripts/check-idris2-proofs.sh (Proof Gate workflow on push/PR).
27+
# The gate HARD-FAILS when idris2 is absent and rejects axiom smuggling
28+
# (postulate / believe_me / assert_total / %hint outside comments).
29+
proof-modules = 13
30+
proof-modules-passing = 13
31+
provers-verified = ["Idris 2 0.7.0", "Idris 2 0.8.0 (nixpkgs)"]
32+
last-verified = "2026-07-21"
2433

2534
[route-to-mvp]
2635
milestones = [
27-
{ name = "Phase 0: Core scaffolding (justfile, CI/CD, .machine_readable)", completion = 100 },
28-
{ name = "Phase 1: ABI/FFI standard (Idris2/Zig templates)", completion = 100 },
29-
{ name = "Phase 1b: AI Gatekeeper Protocol (0-AI-MANIFEST.a2ml)", completion = 100 },
30-
{ name = "Phase 1c: TOPOLOGY.md standard and guide", completion = 100 },
31-
{ name = "Phase 1d: Maintenance gate (axes, checklist, approach)", completion = 100 },
32-
{ name = "Phase 1e: Trustfile / contractiles", completion = 100 },
33-
{ name = "Phase 2: Container ecosystem templates (stapeln)", completion = 100 },
34-
{ name = "Phase 3: Multi-forge sync hardening", completion = 0 },
35-
{ name = "Phase 4: Nix/Guix reproducible shells", completion = 50 },
36+
{ name = "Route α: L1-L7 native Idris 2, verified", completion = 100 },
37+
{ name = "Route α: L8 refinement (dependent-pair encoding), L9 sessions (Brady indexed monad)", completion = 100 },
38+
{ name = "Route α: L10 cubical — WALL, documented as impossible on this route", completion = 100 },
39+
{ name = "Proof gate: script + Justfile + CI (cannot silently pass)", completion = 100 },
40+
{ name = "Route δ: typell bridge (routes/delta-aggregate/TYPELL-BRIDGE.adoc)", completion = 40 },
41+
{ name = "Route δ: full aggregate (F*/LH + Scribble + Agda --cubical over one ABI)", completion = 0 },
42+
{ name = "Routes β, γ: not started", completion = 0 },
43+
{ name = "Route ε: research phase (Nuyts/Devriese 2023, Gratzer et al. 2024)", completion = 5 },
3644
]
3745

3846
[blockers-and-issues]
39-
# No active blockers
47+
issues = [
48+
"src/interface/ffi is uninstantiated RSR template scaffold ({{project}} placeholders, does not compile under any zig) — quarantined in TOPOLOGY.md; instantiate or remove when a route needs a C ABI",
49+
"13 stale remote branches, all unmerged by commit-graph (probable squash-merge artifacts) — prune needs per-branch content diff",
50+
]
4051

4152
[critical-next-actions]
4253
actions = [
43-
"Container templates complete — test with `just container-init`",
44-
"Validate container templates across wolfi-base and static Chainguard images",
45-
"Harden multi-forge sync for GitLab/Bitbucket mirroring edge cases",
46-
"Expand Nix/Guix development shell templates",
54+
"Land typell conformance suite (typell repo: crates/typell-core/tests/kategoria_conformance.rs)",
55+
"Decide src/interface/ffi disposition (instantiate for route δ ABI vs remove)",
56+
"Route δ next step: Agda --cubical bridge prototype for L10",
4757
]
4858

49-
[maintenance-status]
50-
last-run-utc = "never"
51-
last-report = "docs/reports/maintenance/latest.json"
52-
last-result = "unknown" # unknown | pass | warn | fail
53-
open-warnings = 0
54-
open-failures = 0
55-
5659
[ecosystem]
57-
part-of = ["RSR Framework", "stapeln ecosystem"]
58-
depends-on = ["stapeln", "selur-compose", "cerro-torre", "svalinn", "vordr", "k9-svc"]
59-
60-
# ---------------------------------------------------------------------------
61-
# NOTE FOR CONSUMERS: When using this template to create a new repo, reset
62-
# the fields above to your project's values and replace all {{PLACEHOLDER}}
63-
# tokens. The milestones above describe the TEMPLATE's evolution, not yours.
64-
# ---------------------------------------------------------------------------
60+
part-of = ["hyperpolymath type-safety programme"]
61+
related = ["typell (aggregate-style verification kernel; bridge registered)", "panll (consumes typell)", "007", "typed-wasm", "nextgen-languages"]

.tool-versions

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1 @@
1-
# Uncomment and customize for your project
2-
# rust nightly
3-
# just 1.40.0
4-
# nickel 1.10.0
5-
# gleam 1.8.0
6-
# elixir 1.18.0
7-
# erlang 27.2
8-
# zig 0.14.0
9-
# idris2 0.7.0
10-
rust nightly
1+
idris2 0.7.0

Justfile

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,8 @@ init:
265265
# ═══════════════════════════════════════════════════════════════════════════════
266266

267267
# Build the project (debug mode)
268-
build *args:
269-
@echo "Building {{project}} (debug)..."
270-
# TODO: Replace with your build command
271-
# Examples:
272-
# cargo build {{args}} # Rust
273-
# mix compile {{args}} # Elixir
274-
# zig build {{args}} # Zig
275-
# deno task build {{args}} # Deno/ReScript
268+
build *args: proof-check
269+
@echo "kategoria's build IS type-checking: proof-check ran above."
276270
@echo "Build complete"
277271

278272
# Build in release mode with optimizations
@@ -309,15 +303,12 @@ clean-all: clean
309303
# ═══════════════════════════════════════════════════════════════════════════════
310304

311305
# Run all tests
312-
test *args:
313-
@echo "Running tests..."
314-
# TODO: Replace with your test command
315-
# Examples:
316-
# cargo test {{args}}
317-
# mix test {{args}}
318-
# zig build test {{args}}
319-
# deno test {{args}}
320-
@echo "Tests passed!"
306+
test *args: proof-check
307+
308+
# Type-check all 13 verified Idris 2 modules (the repo's real substance).
309+
# Hard-fails when idris2 is absent — a gate that skips is not a gate.
310+
proof-check:
311+
./scripts/check-idris2-proofs.sh
321312

322313
# Run tests with verbose output
323314
test-verbose:

README.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,15 +236,26 @@ field reports.
236236

237237
| Route | L1 | L2 | L3 | L4 | L5 | L6 | L7 | L8 | L9 | L10 |
238238
|-------------|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
239-
| α Extend | | | | | | | | | | |
240-
| β Dyadic | | | | | | | | | | |
241-
| γ Aspect | | | | | | | | | | |
242-
| δ Aggregate | | | | | | | | | | |
243-
| ε Clean | | | | | | | | | | |
239+
| α Extend | | | | | | | | | | |
240+
| β Dyadic | . | . | . | . | . | . | . | . | . | . |
241+
| γ Aspect | . | . | . | . | . | . | . | . | . | . |
242+
| δ Aggregate | . | . | . | . | . | . | . | . | . | . |
243+
| ε Clean | . | . | . | . | . | . | . | . | . | . |
244244

245245
*(✓ = passing, ~ = partial, . = not started, ✗ = proven impossible on
246246
this route)*
247247

248+
Route α's row is enforced by CI: `scripts/check-idris2-proofs.sh` type-checks
249+
all 13 modules (verified under Idris 2 0.7.0 and 0.8.0) and rejects axiom
250+
smuggling. L8 and L9 pass via encodings (dependent pairs; Brady's indexed
251+
monad); L10 is route α's documented wall — see
252+
`routes/alpha-extend/Level10_CubicalTypes.idr`.
253+
254+
Route δ has a measurement bridge before it has an implementation: the
255+
[typell](https://github.com/hyperpolymath/typell) verification kernel is a
256+
live aggregate-style engine mapped level-by-level in
257+
[`routes/delta-aggregate/TYPELL-BRIDGE.adoc`](routes/delta-aggregate/TYPELL-BRIDGE.adoc).
258+
248259
# Level 11 and Beyond
249260

250261
> [!IMPORTANT]

ROADMAP.adoc

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
= Kategoria Roadmap
33
:author: Jonathan D.A. Jewell
44

5-
== Current Status (2026-03-29)
5+
== Current Status (2026-07-21)
66

7-
Route α (Extend Idris 2) is the most advanced route.
7+
Route α (Extend Idris 2) is the most advanced route. All 13 modules
8+
(10 levels + 3 demos) pass `idris2 --check` under Idris 2 0.7.0 AND 0.8.0
9+
with no postulates, believe_me, or %hint smuggling — enforced by
10+
`scripts/check-idris2-proofs.sh` (the Proof Gate workflow runs it on every
11+
push and PR).
812

913
=== Route α Progress
1014

@@ -14,23 +18,31 @@ Route α (Extend Idris 2) is the most advanced route.
1418

1519
| 1 | Basic Types | ✓ | `Level01_BasicTypes.idr`
1620
| 2 | ADTs | ✓ | `Level02_ADTs.idr`
17-
| 3 | Parametric Polymorphism | ✓ | Native (Idris 2)
18-
| 4 | Higher-Kinded Types | ✓ | Native (Idris 2)
19-
| 5 | GADTs | ✓ | Native (Idris 2)
21+
| 3 | Parametric Polymorphism | ✓ | `Level03_Polymorphism.idr`
22+
| 4 | Type Classes | ✓ | `Level04_TypeClasses.idr`
23+
| 5 | GADTs | ✓ | `Level05_GADTs.idr`
2024
| 6 | Dependent Types | ✓ | `Level06_DependentTypes.idr`
21-
| 7 | Linear Types | ✓ | Native (QTT)
22-
| 8 | Refinement Types | ~ | Elaborator sugar in progress
23-
| 9 | Session Types | ✓ | `Level09_SessionTypes.idr`
24-
| 10 | Cubical/Homotopy | ✗ | `Level10_CubicalTypes.idr` (wall documented)
25+
| 7 | Linear Types | ✓ | `Level07_LinearTypes.idr` (native QTT)
26+
| 8 | Refinement Types | | `Level08_Refinement.idr` (dependent-pair encoding, auto-search proofs)
27+
| 9 | Session Types | ✓ | `Level09_SessionTypes.idr` (Brady indexed-monad encoding)
28+
| 10 | Cubical/Homotopy | ✗ | `Level10_CubicalTypes.idr` (wall documented; type-checks as an honest engineering record, does not deliver univalence)
2529
|===
2630

27-
*Route α score: 9/10 (8 native + 1 encoding, 1 impossible)*
31+
*Route α score: 9/10 (7 native + 2 encodings, 1 impossible)*
2832

2933
=== Other Routes
3034

3135
- **Route β (Dyadic)**: Not started. Next priority for L10.
3236
- **Route γ (Aspect)**: Not started. L10 as aspect is risky (see cross-pollination #001).
33-
- **Route δ (Aggregate)**: Not started. Bridge to Agda --cubical is fastest path to L10.
37+
- **Route δ (Aggregate)**: Opened 2026-07-21 via the typell bridge —
38+
link:routes/delta-aggregate/TYPELL-BRIDGE.adoc[TYPELL-BRIDGE.adoc] maps the
39+
https://github.com/hyperpolymath/typell[typell] verification kernel
40+
(a live aggregate-style engine: HM + dependent lengths + QTT/linear +
41+
effects + sessions + refinement/SMT + dimensional, 225 kernel tests) onto
42+
kategoria's levels. Typell is NOT the full route δ prescription
43+
(Idris 2 + F*/Liquid Haskell + Scribble + Agda --cubical over one ABI),
44+
but it is the first concrete aggregate implementation to measure against.
45+
Bridge to Agda --cubical remains the fastest path to L10.
3446
- **Route ε (Clean Slate)**: Research phase. Reading Nuyts & Devriese (2023), Gratzer et al. (2024).
3547

3648
== Milestones
@@ -39,8 +51,9 @@ Route α (Extend Idris 2) is the most advanced route.
3951
* [x] L1-L7: Native Idris 2 coverage verified
4052
* [x] L9: Session types via indexed monad encoding
4153
* [x] L10: Wall documented with best-effort encoding
42-
* [ ] L8: Refinement types via elaborator sugar
43-
* [ ] Shared test suite: all challenge programs automated
54+
* [x] L8: Refinement types via dependent-pair encoding (2026-06; `%auto_implicit_depth` for literal bounds)
55+
* [x] Route α programs automated: `just proof-check` + Proof Gate CI (2026-07-21)
56+
* [ ] Shared test suite generalized across routes (only α has code today)
4457

4558
=== v0.2.0 — Second Route Begins
4659
* [ ] Route δ: Bridge to Agda --cubical for L10

0 commit comments

Comments
 (0)