Repository navigation
audit: routing/rule-engine recon, Logtalk quarantine; Agda proofs re-checked under PROOF-POLICY §2.1 #455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
audit: routing/rule-engine recon, Logtalk quarantine; Agda proofs re-checked under PROOF-POLICY §2.1 #455
Changes from all commits
df5e041
a68b601
4b6fd97
59e88cd
1283392
2398794
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| .hypatia-ignore | ||
| CLAUDE.md | ||
| build/ # build orchestration: guix.scm relocated here (canon 1.2.1 guix-primary template_ref = "build/") | ||
| archive/ # quarantine for dead sources (2026-11-01; Logtalk, see archive/logtalk/README.adoc) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| // SPDX-License-Identifier: CC-BY-SA-4.0 | ||
| // SPDX-FileCopyrightText: 2026 ECHIDNA Project Contributors | ||
|
|
||
| = Quarantine: Logtalk sources | ||
|
|
||
| *Status*: dead source, retained as a record. *Quarantined*: 2026-11-01. | ||
| *Read this first*: nothing here is built, imported, tested or shipped. | ||
|
|
||
| == Contents | ||
|
|
||
| [width="100%",cols="38%,62%",options="header"] | ||
| |=== | ||
| |File |Status | ||
|
|
||
| |`+security_learning.lgt+` | ||
| |DEAD. Was `+rules/security_learning.lgt+`, the only Logtalk module in the | ||
| tree (234 lines, two objects, dated 2025-12-29). Body unchanged; a | ||
| `+DEAD SOURCE+` header records the evidence. | ||
| |=== | ||
|
|
||
| == Why it is here and not in `+rules/+` | ||
|
|
||
| Four questions decided it, and each one alone would have been enough: | ||
|
|
||
| . *Nothing loaded it.* No test, workflow, Justfile recipe, A2ML manifest or | ||
| Cargo build step named the file. `+grep -rn '\.lgt' --exclude-dir=.git .+` | ||
| returned it and one self-reference inside it. No Logtalk runtime is | ||
| installed in CI, and none is declared anywhere. | ||
| . *Its input was a machine-local path.* `+cicd_repo_path('~/repos/cicd-hyper-a/.audittraining')+` | ||
| — a literal `+~+` in a path the module opens. | ||
| . *Its learning step cannot learn.* `+load_training_data/1+` reads Prolog | ||
| terms with `+read/2+`, but the catalog it is pointed at is Scheme | ||
| (`+ERROR-CATALOG.scm+`). Every term reaches the catch-all clause | ||
| `+process_training_term(_)+`, so `+learn_rules/0+` re-asserts the static | ||
| tables already in the file. The output is a transcript of the input | ||
| constants. | ||
| . *The estate moved.* Rule authoring is Elixir in | ||
| https://github.com/hyperpolymath/hypatia[hypatia]. ECHIDNA is a Hypatia | ||
| *target* (`.hypatia-baseline.json`, `.hypatia-ignore`), never a Logtalk | ||
| rule producer. The prose that described Logtalk generation was retired in | ||
| `+docs/ECOSYSTEM-INTEGRATION.adoc+` and | ||
| `+echidna-playground/.machine_readable/descriptiles/NEUROSYM.a2ml+` in the | ||
| same change. | ||
|
|
||
| `+rules/+` was removed rather than left empty, so that the tree cannot imply | ||
| by its shape that ECHIDNA carries rules in Logtalk. | ||
|
|
||
| The full audit, including the path classification and the reproduction | ||
| commands, is | ||
| link:../../docs/reports/2026-11-01-routing-and-rule-engine-recon.adoc[`+docs/reports/2026-11-01-routing-and-rule-engine-recon.adoc+`] | ||
| §4. | ||
|
|
||
| == What it would take to revive this | ||
|
|
||
| Not a rename and not a wrapper. All five, or it stays dead: | ||
|
|
||
| . A Logtalk or compatible Prolog runtime in CI, pinned the way every other | ||
| toolchain in this repo is pinned. | ||
| . A parameterised input path — no `+~+`, no home directory. | ||
| . A real parser for whatever format the catalog actually is, with a fixture | ||
| test per term shape. | ||
| . A named consumer in this repository or a sibling, with a contract. | ||
| . A reason not to write it in Elixir like the rest of the estate's rules. | ||
|
|
||
| == Licence | ||
|
|
||
| MPL-2.0, unchanged, per the `+SPDX-License-Identifier+` header in the file | ||
| and the `+Files: archive/*+` stanza in `+.reuse/dep5+`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,8 +70,10 @@ let deployment = { | |
| container = { | ||
| image = "ghcr.io/hyperpolymath/echidna", | ||
| port = 8081, | ||
| health_check = "/health", | ||
| readiness_check = "/ready", | ||
| # The core server serves /api/health; there is no separate /ready or | ||
| # bare /health route (see src/rust/server.rs), so both probes use it. | ||
| health_check = "/api/health", | ||
| readiness_check = "/api/health", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| }, | ||
| strategy = { | ||
| type = "rolling", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,9 +15,13 @@ Two non-negotiable invariants govern every design choice: | |
| . *ML suggests; provers verify.* Neural components rank, route, and | ||
| propose; formal provers carry the trust. A wrong suggestion is a wasted | ||
| CPU cycle, not a wrong proof. | ||
| . *Trust is checked, not asserted.* Solver binaries are SHAKE3-512 / | ||
| BLAKE3 integrity-checked before invocation; certificates are | ||
| independently reproduced where formats allow (Alethe, DRAT/LRAT, TSTP). | ||
| . *Trust is checked, not asserted.* Certificates are independently | ||
| reproduced where formats allow (Alethe, DRAT/LRAT, TSTP) — that part is | ||
| real. Solver *identity* is not checked today: the integrity step exists, | ||
|
Comment on lines
+19
to
+20
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not claim independent Alethe verification.
|
||
| nothing in the tree attaches a checker, so binaries are currently | ||
| _assumed_ rather than verified. See the Integrity caveat below and | ||
| link:DEBT.adoc[`+DEBT+`] D9. Do not read this list as a guarantee that | ||
| the binary you invoked is the binary you pinned. | ||
|
|
||
| === Component map | ||
|
|
||
|
|
@@ -31,8 +35,8 @@ independently reproduced where formats allow (Alethe, DRAT/LRAT, TSTP). | |
| │ Rust Core (src/rust/, crates/) │ | ||
| │ │ | ||
| │ ┌──────────┐ ┌──────────────┐ ┌────────────────┐ ┌──────────────┐ │ | ||
| │ │ CLI/REPL │ │ REST / GraphQL│ │ gRPC │ │ FFI (Zig) │ │ | ||
| │ │ (main.rs)│ │ (axum :8000) │ │ (tonic :50051)│ │ (16 exports) │ │ | ||
| │ │ CLI/REPL │ │ REST │ │ gRPC │ │ FFI (Zig) │ │ | ||
| │ │ (main.rs)│ │ (axum :8081) │ │ (tonic :50051)│ │ (16 exports) │ │ | ||
| │ └────┬─────┘ └──────┬────────┘ └──────┬────────┘ └──────┬───────┘ │ | ||
| │ └────────────────┴──────────────────┴────────────────┘ │ | ||
| │ │ │ | ||
|
|
@@ -103,7 +107,14 @@ link:handover/TODO.adoc[`+handover/TODO.adoc+`] for current state): | |
|
|
||
| [arabic] | ||
| . *Integrity* (`+integrity/+`) — solver binary SHAKE3-512 + BLAKE3 | ||
| against `+config/solver-manifest.toml+`. | ||
| against `+config/solver-manifest.toml+`. *Caveat, 2026-11-01*: this step | ||
| runs only when a checker is attached, and nothing in the tree calls | ||
| `+with_integrity_checker+`; unconfigured, the pipeline treats integrity as | ||
| passing (`+dispatch.rs:632+`). The manifest also still holds | ||
| `+PLACEHOLDER_COMPUTE_ON_FIRST_RUN+` for every solver. Treat this step as | ||
| *not executed* until it is wired; see | ||
| link:reports/2026-11-01-routing-and-rule-engine-recon.adoc[`+docs/reports/2026-11-01-routing-and-rule-engine-recon.adoc+`] | ||
| §6 RD5. | ||
| . *Dispatch* (`+dispatch.rs+`) — `+ProverDispatcher::select_prover+` | ||
| picks the backend; under `+with_verisim+`, `+VeriSimAdvisor+` queries | ||
| `+mv_prover_success_by_class+` for historical success-rate hints. | ||
|
|
@@ -127,6 +138,49 @@ updates. | |
| `+with_verisim_writer+`) — fire-and-forget write to VeriSimDB | ||
| `+proof_attempts+`, closes the learning loop. | ||
|
|
||
| === Client-facing surfaces, and what VeriSimDB is not | ||
|
|
||
| There are *four independent listeners*, not one service on four ports. Each is | ||
| a separate binary with its own route table and its own path to the provers: | ||
|
|
||
| [width="100%",cols="30%,16%,54%",options="header",] | ||
| |=== | ||
| |Listener |Default bind |Route root | ||
|
|
||
| |`+echidna server+` |`+127.0.0.1:8081+` |`+/api/*+` — `/api/health`, | ||
| `+/api/provers+`, `/api/prove`, `/api/verify`, `/api/session/*`, … | ||
| |`+echidna-rest+` |`+127.0.0.1:8000+` |`+/api/v1/*+` plus root `+/health+` | ||
| |`+echidna-graphql+` |`+127.0.0.1:8081+` |`+POST /+` (GraphQL), `+GET /+` | ||
| (playground), `+/health+` | ||
| |`+echidna-grpc+` |`+[::1]:50051+` |`+ProofService+` over `+echidna.proto+` | ||
| |=== | ||
|
|
||
| `+echidna server+` and `+echidna-graphql+` share a default port; start only one | ||
| without setting `+ECHIDNA_GRAPHQL_ADDR+`. The one-port-per-project rule is | ||
| `+0-canon/PORT-REGISTRY.adoc+` in hyperpolymath/standards; the collision is | ||
| open debt. | ||
|
|
||
| *VeriSimDB is a persistence and learning adapter, not a communication path.* | ||
| It sits behind the non-default `+verisim+` Cargo feature, is written to | ||
| fire-and-forget after a dispatch, and is never consulted to reach a prover. | ||
| Clients do not route through it, and *must not* need to: the estate's | ||
| `+3-practice/PROOF-POLICY.adoc+` §2.2 states that ECHIDNA is "`the | ||
| longer-term automation destination, not a prerequisite for current independent | ||
| checks`". A mandatory VCL hop would violate that. Two consequences worth | ||
| knowing before you deploy: | ||
|
|
||
| * Enabling `+verisim+` also moves `+POST /api/prove+` onto `+ProverDispatcher+` | ||
| (`+server.rs:423+`); without it, `/api/prove` goes to the backend factory | ||
| directly. A storage feature should not decide the verification route. | ||
| * `/api/verify` never enters the dispatcher at all, and `/api/verify_raw` | ||
| executes the solver binary directly by design. | ||
|
|
||
| So "which pipeline ran" depends on the surface and the feature set. If a client | ||
| needs a machine-readable answer it can trust, use `+echidna prove <file> | ||
| --output json+` — the documented | ||
| link:PROVE-RESULT-CONTRACT.adoc[`+echidna.prove.result/1+`] contract — rather | ||
| than inferring it from an HTTP response body. | ||
|
|
||
| === Polyglot source layout | ||
|
|
||
| `+src/+` holds one subdirectory per language. The split is intentional — | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When an orphan source has the same basename as another local or standard-library module—for example
src/Echidna/Experimental/Dispatch.agda—this basename-only lookup accepts the existingDispatch.agdaieven if the new source was never imported or type-checked. That silently recreates the exact unchecked-module failure this step is intended to prevent; compare qualified module identities/paths or invoke Agda for each source rather than discarding all directory information.Useful? React with 👍 / 👎.