Lightweight proof-workspace manager for Agda — the language-agnostic
engine half of arghda. Extracted from
hyperpolymath/echo-types
to its own repository on 2026-05-30 (see echo-types#159 for the move
record).
arghda-core organises, lints, and reports on an Agda proof workspace; it never proves anything itself — Agda does. It manages a four-state triage workspace (inbox → working → proven → rejected) as file moves, runs a lint pack targeting the silent-failure class (cases where Agda appears to succeed but the file is not actually in the verified suite), builds a first-class import-graph DAG, and emits a JSON + event-stream contract a visual layer consumes.
v0.1 is feature-complete against docs/arghda-spec.adoc: all seven v0
Agda lint rules, the four-state workspace state machine, the
import-graph dag, the check command (Agda typecheck + lint
verdict), content-hash invalidation of proven, and
.arghda/config.toml operator configuration. The live status of
record is STATE.a2ml.
Hard-block (forbids the working → proven transition):
-
missing-safe-pragma— file lacks{-#OPTIONS--safe--without-K#-}. -
orphan-module—.agdafile unreachable from any CI root (roots are auto-discovered asAll.agda/Smoke.agda, or passed via--entry; reachability is the union, so a module verified from any root is not an orphan). -
unjustified-postulate—postulatewithout an adjacent--JUSTIFY:comment.
Warn (surfaced, non-blocking):
-
escape-hatch— termination overrides (TERMINATING,NON_TERMINATING,NO_TERMINATION_CHECK) and trust primitives (believe_me/primTrustMe). -
tab-mix— a tab in leading whitespace. -
unpinned-headline— a top-level theorem whose name matches the headline pattern is not pinned in anySmoke.agdavia ausing(…)clause (the estate “every headline pinned in Smoke” discipline). The pattern is operator-configurable; its default^[a-z][A-Za-z0-9-]*$is deliberately broad, so operators narrow it to their own convention. Self-skips when noSmoke.agdais in scope. -
unused-import— re-emits the findings of the externalagda-unusedtool. Opt-in behindscan--unused; invoked per file in local mode withLC_ALL=C.UTF-8; skipped with a note if the binary is not onPATH.
The CLI is arghda.
| Command | What it does |
|---|---|
|
Create the four-state workspace layout at a path. |
|
Lint every |
|
Run Agda on one file and lint it; combined verdict (degrades
when |
|
Emit the dependency-DAG JSON — nodes (lint status + declared
|
|
State-machine transitions; each is a file move logged to
|
|
Replay the workspace event log. |
|
List |
|
Watch |
scan and dag read .arghda/config.toml (from
<PATH>/.arghda/config.toml, or an explicit --config <file>).
Precedence is built-in default < config.toml < CLI flag.
[lint]
headline_pattern = "^[a-z][A-Za-z0-9-]*$"just check # fmt-check + clippy (-D warnings) + build + test — the CI gate
cargo build
cargo testagda and agda-unused are optional: the check and scan
--unused paths degrade gracefully (with a note) when the binary is
absent, so the rest of the engine still works in an Agda-less
environment.
cargo run -- scan path/to/your/agda/sourcesDogfooded against the echo-types corpus (193 modules): dag emits the
903-edge import graph; multi-root discovery (All.agda,
Smoke.agda, Ordinal/Buchholz/Smoke.agda,
characteristic/All.agda, examples/All.agda) narrows orphan
reports from 38 to the 17 genuine orphans.
Part of the hyperpolymath ecosystem.
arghda splits into arghda-core (this engine) and the planned
arghda-studio / arghda-panll visual layers, which consume the
dag JSON + events.jsonl contract. The motivating workspace was
the echo-types proof pipeline, but arghda-core has no
echo-types-specific code.
Adjacent projects:
-
echo-types — the Agda library that motivated arghda’s design (not a build dependency).
-
absolute-zero — a sister Agda library under the same
--safe--without-Kdiscipline.
Per the Rhodium Standard, structured project metadata lives under
.machine_readable/6a2/ — STATE,
META, ECOSYSTEM, AGENTIC, NEUROSYM, PLAYBOOK in A2ML
— with 0-AI-MANIFEST.a2ml as the AI entry
point and EXPLAINME.adoc as the orientation
pointer.
Code, configuration and scripts are MPL-2.0 (see LICENSE); prose
documentation is CC-BY-SA-4.0, per the
hyperpolymath licence policy
(Rule 1). This split is a formal invariant: every tracked file carries
the appropriate SPDX header, checked by scripts/check-spdx.sh in
just check and in CI. Third-party, generated, and test-data
files are explicitly excluded
(licensing-policy.toml)
and are never relicensed — vendoring third-party source in-tree fails
the check until it is listed as excluded with its original SPDX
preserved.