Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions AFFIRMATION.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ state and commitments. Companion detail:
`native_decide`). One obligation remains open — neural-convergence
(PageRank + ESN) — blocked only on Mathlib network access; the handover is
at `docs/proofs/HANDOVER-neural-convergence.md`.
* *The hexadeca-connector wire contract cannot silently drift.* The Zig enum,
* *The unified-api-adapter wire contract cannot silently drift.* The Zig enum,
the Idris2 ABI and the Rust client are pinned to one golden source
(`ffi/connectors.json`) by `test/hexadeca_contract_test.exs` under
(`ffi/connectors.json`) by `test/unified-api-adapter-contract_test.exs` under
`mix test`.
* *Workflow hygiene.* Every runner job declares `timeout-minutes`; the
`workflow_audit` rule no longer false-positives reusable-workflow
Expand All @@ -38,7 +38,7 @@ state and commitments. Companion detail:
== We intend (planned — INTEND)

* Deploy *verisim-api* (the VeriSimDB Rust core) to unlock native
graph/vector/temporal modalities and let the hexadeca transport bodies be
graph/vector/temporal modalities and let the unified-api-adapter transport bodies be
fleshed out on demand.
* Ensure merged rule fixes reach *live* self-scans — the deployed scanner
currently lags `main` (issue #484).
Expand Down
2 changes: 1 addition & 1 deletion clients/rust/hypatia-client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: MPL-2.0
[package]
name = "hypatia-client"
description = "Rust client for the Hypatia hexadeca-connector surface (FFI primary, subprocess fallback)"
description = "Rust client for the Hypatia unified-api-adapter surface (FFI primary, subprocess fallback)"
version.workspace = true
edition.workspace = true
authors.workspace = true
Expand Down
8 changes: 4 additions & 4 deletions clients/rust/hypatia-client/src/connector.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
//
// Hexadeca-Connector enum — mirror of the Zig
// `Connector` enum in `ffi/zig/src/hexadeca.zig` and the Idris2
// UnifiedApiAdapter enum — mirror of the Zig
// `Connector` enum in `ffi/zig/src/unified-api-adapter.zig` and the Idris2
// `Connector` data type in `src/abi/Types.idr`.
//
// **Wire ordering is load-bearing.** The integer value of each variant
Expand All @@ -15,7 +15,7 @@
use serde::{Deserialize, Serialize};

/// The sixteen protocol connectors exposed by the Hypatia
/// hexadeca-connector surface.
/// unified-api-adapter surface.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u8)]
pub enum Connector {
Expand All @@ -40,7 +40,7 @@ pub enum Connector {
}

/// The total number of connectors. Pinned at 16 by the
/// `comptime` assertion in `hexadeca.zig` and the
/// `comptime` assertion in `unified-api-adapter.zig` and the
/// `connectorCount : length allConnectors = 16` proof in
/// `src/abi/Types.idr`.
pub const CONNECTOR_COUNT: usize = 16;
Expand Down
8 changes: 4 additions & 4 deletions clients/rust/hypatia-client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
//
// hypatia-client — Rust client for the Hypatia hexadeca-connector
// hypatia-client — Rust client for the Hypatia unified-api-adapter
// surface. Replaces the deleted V-lang client at `api/v/hypatia.v`.
//
// Two transports, picked at runtime:
Expand All @@ -16,14 +16,14 @@
// types defined in `types.rs`. Consumers (e.g. 007 F7) only see the
// `Client` API; transport selection is invisible.
//
// The hexadeca surface itself (16 protocol adapters: gRPC, GraphQL,
// The unified-api-adapter surface itself (16 protocol adapters: gRPC, GraphQL,
// REST, FlatBuffers, Bebop, JSON-RPC, WebSocket, MQTT, tRPC,
// Cap'n Proto, SOAP, VeriSimDB-REST, BSP, SCIP, IPFS, Arrow Flight)
// lives on the Zig side at `hypatia/ffi/zig/src/hexadeca.zig` and is
// lives on the Zig side at `hypatia/ffi/zig/src/unified-api-adapter.zig` and is
// mirrored by the Idris2 ABI in `src/abi/Types.idr`. The Rust client
// knows about all sixteen via `Connector` so that future enumeration
// and dispatch endpoints (`hypatia_connector_count`,
// `hypatia_connector_name`, `hypatia_hexadeca_start_all`) are
// `hypatia_connector_name`, `hypatia_unified_api_adapter_start_all`) are
// type-safe end-to-end.

pub mod client;
Expand Down
2 changes: 1 addition & 1 deletion docs/DEBT-REGISTER.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ fixture. The 5 real Lean proofs contain no `+sorry+`.
==== P-3 · MEDIUM · Zig FFI correctness claims are entirely ungated · UNTRACKED

`+ffi/zig/+` holds 20+ files including 16 protocol connectors and
`+hexadeca.zig+`. There is *no `+zig build+` and no `+zig build test+`
`+unified-api-adapter.zig+`. There is *no `+zig build+` and no `+zig build test+`
in any workflow* — only incidental `+--include='*.zig'+` grep filters.
`+Justfile:94+` has `+zig build+`, never invoked by CI. The "`18
exported C functions`" claim is unverified by any gate.
Expand Down
4 changes: 2 additions & 2 deletions docs/design/estate-audit-workflow-draft.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ jobs:
- name: Idris2 ABI Purity Gate
uses: hyperpolymath/cicd-suite/actions/idris2-abi-check@main

- name: Zig Hexadeca API Gate
uses: hyperpolymath/cicd-suite/actions/zig-hexadeca-check@main
- name: Zig UnifiedApiAdapter API Gate
uses: hyperpolymath/cicd-suite/actions/zig-unified-api-adapter-check@main

- name: Contractile Validation Gate
uses: hyperpolymath/cicd-suite/actions/contractile-validation-check@main
Expand Down
2 changes: 1 addition & 1 deletion docs/governance/CRG-AUDIT-2026-04-18.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ hits, contractile trident complete, full mirror fan-out configured.

| Zig FFI modules (`ffi/zig/src/*.zig`)
| 4 files, 724 LOC
| `main.zig` 274, `hexadeca.zig` 230, `json_writer.zig` 144, `file_ops.zig` 76. Seven exported C ABI functions per `.claude/CLAUDE.md`.
| `main.zig` 274, `unified-api-adapter.zig` 230, `json_writer.zig` 144, `file_ops.zig` 76. Seven exported C ABI functions per `.claude/CLAUDE.md`.

| Elixir rule modules (`lib/rules/*.ex`)
| *19* modules, 6,791 LOC
Expand Down
4 changes: 2 additions & 2 deletions docs/status/estate-musts-intends-wishes-2026-06-19.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ CLAUDE) and lack only a formal CRG grade.

Core three bots + coordinator are Grade B/Beta and operating estate-wide
(1635 dispatches, 99% success). The 2026-06 session cleared the estate’s
Nix→Guix, CI-timeout, workflow_audit-FP and hexadeca-contract musts. The
Nix→Guix, CI-timeout, workflow_audit-FP and unified-api-adapter-contract musts. The
big live workstream is the merge-orchestration runtime (parallel
session, now merged in hypatia). Remaining musts are mostly blocked on
the owner.
Expand All @@ -28,7 +28,7 @@ the owner.
triage (#470/#369) · M13 SARIF / M14 GraphQL / M15 auth |Nx/EXLA backend
· cross-org VCL federation · flesh out bebop/capnproto bodies on demand

|✅ this session: hexadeca contract drift-guarded (#510) + documented
|✅ this session: unified-api-adapter contract drift-guarded (#510) + documented
(#511); workflow_audit FPs fixed (#462); Guix-only; CI timeouts | |
|===

Expand Down
2 changes: 1 addition & 1 deletion ffi/connectors.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"_spdx": "MPL-2.0",
"_note": "Golden source-of-truth for the hexadeca-connector wire contract. The Zig enum (ffi/zig/src/hexadeca.zig), the Idris2 ABI (src/abi/Types.idr), and the Rust client (clients/rust/hypatia-client/src/connector.rs) MUST all agree with this list, in this exact order; id is the C ABI wire id. Drift is guarded by test/hexadeca_contract_test.exs. Wire ordering is load-bearing -- do not renumber.",
"_note": "Golden source-of-truth for the unified-api-adapter wire contract. The Zig enum (ffi/zig/src/unified-api-adapter.zig), the Idris2 ABI (src/abi/Types.idr), and the Rust client (clients/rust/hypatia-client/src/connector.rs) MUST all agree with this list, in this exact order; id is the C ABI wire id. Drift is guarded by test/unified-api-adapter-contract_test.exs. Wire ordering is load-bearing -- do not renumber.",
"connectors": [
{ "id": 0, "name": "grpc" },
{ "id": 1, "name": "graphql" },
Expand Down
14 changes: 7 additions & 7 deletions ffi/zig/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ zig build test # run all tests (main, json_writer, file_ops, integration
== Source Files

* `src/main.zig` — All 7 C ABI exports + lifecycle/utility functions
* `src/hexadeca.zig` — 16-protocol Hexadeca-Connector surface + dispatch seam (see below)
* `src/unified-api-adapter.zig` — 16-protocol UnifiedApiAdapter surface + dispatch seam (see below)
* `src/json_writer.zig` — Zero-allocation JSON writer for FFI responses
* `src/file_ops.zig` — verisim-data flat-file I/O helpers
* `src/connectors/` — Per-protocol transport shims (reference fidelity; see below)
* `test/integration_test.zig` — Integration tests against a test data fixture

== Hexadeca-Connector Surface
== UnifiedApiAdapter Surface

Beyond the seven core C ABI functions, `src/hexadeca.zig` defines the
*Hexadeca-Connector*: a sixteen-protocol unified API surface that wraps the
Beyond the seven core C ABI functions, `src/unified-api-adapter.zig` defines the
*UnifiedApiAdapter*: a sixteen-protocol unified API surface that wraps the
same core ABI. Each connector speaks a different transport but routes through
one core, so a consumer talks to Hypatia over whichever wire it prefers.

Expand All @@ -67,18 +67,18 @@ one core, so a consumer talks to Hypatia over whichever wire it prefers.
|===

The integer `id` is the *C ABI wire id*: it is load-bearing and must not be
renumbered. Port layout is `base + id + 1` (`HexadecaSuite.portFor`).
renumbered. Port layout is `base + id + 1` (`UnifiedApiAdapter.portFor`).

=== Tri-language contract

The connector set is mirrored in three places that *must agree*:

* Zig — `ffi/zig/src/hexadeca.zig` (`Connector` enum + `comptime` count assertion)
* Zig — `ffi/zig/src/unified-api-adapter.zig` (`Connector` enum + `comptime` count assertion)
* Idris2 — `src/abi/Types.idr` (`Connector` + the `connectorCount = Refl` proof)
* Rust — `clients/rust/hypatia-client/src/connector.rs` (`#[repr(u8)]` enum)

`ffi/connectors.json` is the *golden source-of-truth*, and
`test/hexadeca_contract_test.exs` (run under `mix test`) fails CI if any of
`test/unified-api-adapter-contract_test.exs` (run under `mix test`) fails CI if any of
the three mirrors drifts in name or order. To add, remove, or reorder a
connector, update the golden fixture and all three mirrors together.

Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/bebop.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 5/16 — Bebop. Stub fidelity; see `hexadeca.zig`.
// Connector 5/16 — Bebop. Stub fidelity; see `unified-api-adapter.zig`.

const std = @import("std");

Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/bsp.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 13/16 — Build Server Protocol. Stub fidelity; see `hexadeca.zig`.
// Connector 13/16 — Build Server Protocol. Stub fidelity; see `unified-api-adapter.zig`.
// Part of the Umoja substrate (BSP/SCIP/IPFS/Arrow Flight).

const std = @import("std");
Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/capnproto.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 10/16 — Cap'n Proto. Stub fidelity; see `hexadeca.zig`.
// Connector 10/16 — Cap'n Proto. Stub fidelity; see `unified-api-adapter.zig`.

const std = @import("std");

Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/flatbuffers.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 4/16 — FlatBuffers. Stub fidelity; see `hexadeca.zig`.
// Connector 4/16 — FlatBuffers. Stub fidelity; see `unified-api-adapter.zig`.

const std = @import("std");

Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/graphql.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 2/16 — GraphQL. Stub fidelity; see `hexadeca.zig` for the
// Connector 2/16 — GraphQL. Stub fidelity; see `unified-api-adapter.zig` for the
// substrate. Real schema/resolver work lands in this file when needed.

const std = @import("std");
Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/grpc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// Stub-fidelity matching the V-lang reference at
// `developer-ecosystem/.../v-ecosystem/v_api_interfaces/v_grpc/`.
// Real socket and protobuf encoding land here when needed; the
// hexadeca substrate is unaffected by the upgrade because all
// unified-api-adapter substrate is unaffected by the upgrade because all
// dispatch routes through the core C ABI in `../main.zig`.

const std = @import("std");
Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/jsonrpc.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 6/16 — JSON-RPC. Stub fidelity; see `hexadeca.zig`.
// Connector 6/16 — JSON-RPC. Stub fidelity; see `unified-api-adapter.zig`.

const std = @import("std");

Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/mqtt.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 8/16 — MQTT. Stub fidelity; see `hexadeca.zig`.
// Connector 8/16 — MQTT. Stub fidelity; see `unified-api-adapter.zig`.

const std = @import("std");

Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/rest.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 3/16 — REST. Stub fidelity; see `hexadeca.zig` for the substrate.
// Connector 3/16 — REST. Stub fidelity; see `unified-api-adapter.zig` for the substrate.

const std = @import("std");

Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/soap.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 11/16 — SOAP. Stub fidelity; see `hexadeca.zig`.
// Connector 11/16 — SOAP. Stub fidelity; see `unified-api-adapter.zig`.

const std = @import("std");

Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/trpc.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 9/16 — tRPC. Stub fidelity; see `hexadeca.zig`.
// Connector 9/16 — tRPC. Stub fidelity; see `unified-api-adapter.zig`.

const std = @import("std");

Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/verisimdb_rest.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 12/16 — VeriSimDB REST. Stub fidelity; see `hexadeca.zig`.
// Connector 12/16 — VeriSimDB REST. Stub fidelity; see `unified-api-adapter.zig`.
//
// Distinct from the generic REST connector (3/16) because VeriSimDB
// has its own modality semantics — when this is fleshed out it will
Expand Down
2 changes: 1 addition & 1 deletion ffi/zig/src/connectors/websocket.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MPL-2.0
// Connector 7/16 — WebSocket. Stub fidelity; see `hexadeca.zig`.
// Connector 7/16 — WebSocket. Stub fidelity; see `unified-api-adapter.zig`.

const std = @import("std");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
//
// Hypatia Hexadeca-Connector — sixteen-protocol unified API surface.
// Hypatia UnifiedApiAdapter — sixteen-protocol unified API surface.
//
// Replaces the V-lang `api/v/hypatia.v` client (deleted 2026-04-13)
// with a Zig-side multi-transport surface that wraps the existing
// Hypatia C ABI core (`hypatia_health_check`, `hypatia_scan_repo`,
// `hypatia_dispatch`, `hypatia_record_outcome`, `hypatia_force_learning_cycle`,
// `hypatia_get_confidence`, `hypatia_dispatch_strategy`).
//
// The hexadeca pattern follows
// The unified-api-adapter pattern follows
// `developer-ecosystem/.../v-ecosystem/v_api_interfaces/v_api_interfaces.v`:
//
// Core 12 protocols
Expand Down Expand Up @@ -126,23 +126,23 @@ const arrow_flight = @import("connectors/arrow_flight.zig");
// Suite — port-table for the sixteen connectors
// ============================================================

pub const HexadecaSuite = struct {
pub const UnifiedApiAdapter = struct {
base_port: u16,

pub fn init(base_port: u16) HexadecaSuite {
pub fn init(base_port: u16) UnifiedApiAdapter {
return .{ .base_port = base_port };
}

/// Returns the bound port for a given connector. Layout matches
/// the V reference: `base + 1` … `base + 16`.
pub fn portFor(self: HexadecaSuite, c: Connector) u16 {
pub fn portFor(self: UnifiedApiAdapter, c: Connector) u16 {
return self.base_port + @as(u16, @intFromEnum(c)) + 1;
}

/// Start every connector. Each module's `start` is currently a
/// log-only stub matching the V reference; real bind happens
/// when each module is fleshed out individually.
pub fn startAll(self: HexadecaSuite) void {
pub fn startAll(self: UnifiedApiAdapter) void {
grpc.start(self.portFor(.grpc));
graphql.start(self.portFor(.graphql));
rest.start(self.portFor(.rest));
Expand Down Expand Up @@ -194,7 +194,7 @@ pub const ConnectorDispatchFn = *const fn (req: []const u8, out: *anyopaque) i32
// Compile-time assertion: the connector table has exactly 16 entries.
comptime {
if (CONNECTOR_COUNT != 16) {
@compileError("Hexadeca-Connector requires exactly 16 connectors");
@compileError("UnifiedApiAdapter requires exactly 16 connectors");
}
}

Expand All @@ -213,7 +213,7 @@ test "connector names are stable" {
}

test "port layout matches v-lang reference" {
const suite = HexadecaSuite.init(8000);
const suite = UnifiedApiAdapter.init(8000);
try std.testing.expectEqual(@as(u16, 8001), suite.portFor(.grpc));
try std.testing.expectEqual(@as(u16, 8012), suite.portFor(.verisimdb_rest));
try std.testing.expectEqual(@as(u16, 8013), suite.portFor(.bsp));
Expand Down
10 changes: 5 additions & 5 deletions src/Hypatia/ABI/Types.idr
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,10 @@ record OutcomeRecord where
bot : String

-- ============================================================
-- Hexadeca-Connector — sixteen protocol adapters
-- UnifiedApiAdapter — sixteen protocol adapters
-- ============================================================
--
-- Mirrors the Zig enum at `ffi/zig/src/hexadeca.zig` and the Rust
-- Mirrors the Zig enum at `ffi/zig/src/unified-api-adapter.zig` and the Rust
-- enum at `clients/rust/hypatia-client/src/connector.rs`. Wire
-- ordering is load-bearing — the integer value of each variant is
-- the C ABI id used by `hypatia_connector_name(id)`. Do not
Expand All @@ -154,7 +154,7 @@ record OutcomeRecord where
-- Replaces the V-lang client at `api/v/hypatia.v` (deleted 2026-04-13).

||| The sixteen protocol connectors exposed by the Hypatia
||| hexadeca-connector surface. Order is the C ABI wire ordering;
||| unified-api-adapter surface. Order is the C ABI wire ordering;
||| see `Hypatia.ABI.Types.connectorWireId` for the mapping.
public export
data Connector
Expand Down Expand Up @@ -198,7 +198,7 @@ connectorWireId IPFS = 14
connectorWireId ArrowFlight = 15

||| Canonical wire name of a connector. Must agree with
||| `Connector.name()` in `ffi/zig/src/hexadeca.zig`.
||| `Connector.name()` in `ffi/zig/src/unified-api-adapter.zig`.
public export
connectorName : Connector -> String
connectorName GRPC = "grpc"
Expand Down Expand Up @@ -228,7 +228,7 @@ allConnectors =
]

||| Proof that there are exactly sixteen connectors. Pins the
||| hexadeca invariant at the type level: any code that adds or
||| unified-api-adapter invariant at the type level: any code that adds or
||| removes a connector must update this proof, which forces a
||| coordinated update of the Zig enum and the Rust client.
public export
Expand Down
Loading
Loading