Skip to content

fix(a2ml): normative Idris2 core now type-checks (10/10 modules) - #567

Merged
hyperpolymath merged 1 commit into
mainfrom
fix/a2ml-core-typechecks-and-gate
Aug 3, 2026
Merged

fix(a2ml): normative Idris2 core now type-checks (10/10 modules)#567
hyperpolymath merged 1 commit into
mainfrom
fix/a2ml-core-typechecks-and-gate

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Completes #556. The normative Idris2 core now type-checks — 10/10 modules, verified locally against idris2 0.7.0.

SPEC.adoc §3.1 calls src/A2ML/ "normative … the source files are authoritative." Nothing built it (no .ipkg anywhere, no CI job) and it did not compile. Since all three dialects must agree through this core, and it's about to be registered with IANA, this is the foundation.

Root causes fixed — no postulate, no believe_me, no assert_total

One mistake caused 7 of the 16 errors: Data.String.strIndex is non-covering in Idris2 0.7.0, so it can never appear under %default totaland peek/char pattern-matched its Char result as if it were Maybe Char. Replaced with a total, covering strIndexSafe.

Problem Fix
Consuming loops (skipWhitespace, countHashes, parseBullets, parseBlocks) had no structural decrease recurse on explicit fuel derived from remaining input
prettyPrint/collectIds/collectRefs recursed via MkDoc s.body a record projection is not structural descent; match MkSec and recurse on List Block
`< >declared inside awhere` block (doesn't resolve there)
collectIds/collectRefs were private AND partial now total + exported
A2ML.Proofs didn't compile at all All used without Data.List.Quantifiers; elemAppend referenced twice but defined nowhere → replaced with elemAppendLeft/elemAppendSplit, each proved by induction on the Elem witness; |> isn't an Idris2 operator; two proofs referenced their own argument before binding it while projecting fields shared by three records
ParserTests tested a nonexistent API (parse, uniqueIdsDec, refsResolveDec, hasAbstractDec) rewritten against the real API
No Eq Id, so tests couldn't compare ids added, delegating to the existing idEq

A real gap this uncovered

A2ML.Surface.SDoc and A2ML.Translator.translate : SDoc -> Doc both exist — but nothing produces an SDoc. There is no surface parser, so that half of the pipeline is unreachable. Worth its own issue; it matters for the dialect-factory design.

Two things deliberately left out

  1. The CI gate isn't in this PR — this token lacks GitHub's workflow scope, so it cannot create .github/workflows/. The workflow is drafted and posted on A2ML normative Idris2 core: A2ML.Parser does not type-check (16 errors) — blocks the core CI gate #556 for you to add. It's a real gate: no continue-on-error, no skip-if-absent, and it uses the ipkg target because per-file idris2 --check exits 0 on a missing module (a fake gate).
  2. A2ML.Converters is excluded from the package and tracked. Its renderers (toMarkdown/toDjot/toHtml/toLatex) are mutually recursive with their own where-block helpers, which can't be total in that shape and needs a hand-done restructure. Including it would make the gate red on arrival. The .ipkg documents this scope explicitly.

Verification: cd a2ml && idris2 --typecheck a2ml-core.ipkg → exit 0, 10/10 modules.

…gate

SPEC.adoc §3.1 calls `src/A2ML/` normative and authoritative. Nothing built it
— no .ipkg anywhere, no CI job — and it did not compile. Now 10/10 modules
type-check under idris2 0.7.0, verified locally, and a real gate enforces it.

No postulate, no believe_me, no assert_total. Root causes:

- Data.String.strIndex is NON-COVERING in 0.7.0, so it can never appear under
  %default total; peek/char also pattern-matched its Char result as if it were
  Maybe Char. That one mistake caused 7 of the 16 unification errors. Replaced
  with a total, covering strIndexSafe.
- Consuming loops (skipWhitespace, countHashes, parseBullets, parseBlocks) had
  no structural decrease; each now recurses on explicit fuel derived from the
  remaining input.
- prettyPrint / collectIds / collectRefs recursed via `MkDoc s.body`. A record
  projection is not structural descent to the termination checker; matching the
  MkSec constructor and recursing on List Block makes the decrease visible.
- `<|>` was declared inside a where block, where it does not resolve. Replaced
  with a top-level `orElse`.
- collectIds/collectRefs were private AND partial, so parseAndValidate could
  not use them. Now total and exported.
- A2ML.Proofs did not compile at all: `All` used without importing
  Data.List.Quantifiers; `elemAppend` referenced twice but defined nowhere
  (replaced by elemAppendLeft/elemAppendSplit, each proved by induction on the
  Elem witness); `|>` is not an Idris2 operator; and two proofs referenced their
  own argument before binding it while projecting fields shared by three records.
- ParserTests tested an API that does not exist (parse, uniqueIdsDec,
  refsResolveDec, hasAbstractDec). Rewritten against the real API — which
  uncovered a genuine gap: Surface.SDoc and Translator.translate exist, but
  NOTHING produces an SDoc. There is no surface parser.
- Added Eq Id, delegating to the existing idEq.

The CI gate could NOT be included here: this token lacks GitHub's `workflow`
scope, so it cannot create `.github/workflows/`. The workflow is drafted and
posted on #556 for the owner to add — it is a real gate (no continue-on-error,
no skip-if-absent) and uses the ipkg target because per-file `idris2 --check`
exits 0 when an import is missing.

A2ML.Converters is deliberately excluded and tracked: its renderers are mutually
recursive with their own where-block helpers and need a hand-done restructure.
Including it would make the gate red on arrival.

Refs #556

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Aug 3, 2026

Copy link
Copy Markdown

@gitar-bot

gitar-bot Bot commented Aug 3, 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 ✅ Approved

Fixes 16 type-checking errors across the normative Idris2 core modules, ensuring all 10 modules now compile cleanly under Idris2 0.7.0. No issues found.

Auto-approved and auto-merge armed: No blocking issues found.
Please see Auto-approve Docs for details on setting custom approval criteria. — merges when pipeline and required approvals pass.

Options

Display: compact → Showing less information.

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

Compact
gitar display:verbose         

Important

Your trial ends in 7 days — upgrade now to keep code review, CI analysis, auto-apply, custom automations, and more.

Was this helpful? React with 👍 / 👎 | Gitar

@gitar-bot
gitar-bot Bot enabled auto-merge (squash) August 3, 2026 12:55

@gitar-bot gitar-bot 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.

Gitar has auto-approved this PR and enabled auto-merge (configure)

@gitar-bot gitar-bot Bot added the gitar-approved Added by Gitar label Aug 3, 2026
@hyperpolymath
hyperpolymath disabled auto-merge August 3, 2026 13:06
@hyperpolymath
hyperpolymath merged commit 0265b62 into main Aug 3, 2026
36 of 39 checks passed
@hyperpolymath
hyperpolymath deleted the fix/a2ml-core-typechecks-and-gate branch August 3, 2026 13:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gitar-approved Added by Gitar

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant