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
2 changes: 1 addition & 1 deletion .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ cargo test
## Key Design Decisions

- Follows hyperpolymath ABI-FFI standard (Idris2 ABI, Zig FFI)
- MPL-2.0 license
- MPL-2.0 license (code) + CC-BY-SA-4.0 (docs); full texts in LICENSES/
- RSR (Rhodium Standard Repository) template
- Author: Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/rhodibot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Reads root-hygiene rules and auto-fixes what it can:
# - Delete banned files (AI.djot, duplicate CONTRIBUTING.adoc, stale snapshots)
# - Rename misnamed files (AI.a2ml → 0-AI-MANIFEST.a2ml)
# - Fix SPDX headers (AGPL → PMPL in dotfiles)
# - Fix SPDX headers (AGPL → MPL-2.0 in dotfiles)
# - Create missing required files (SECURITY.md, CONTRIBUTING.md)
# - Report unfixable issues as PR comments
#
Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:
for dotfile in .gitignore .gitattributes .editorconfig; do
if [ -f "$dotfile" ] && grep -q "AGPL-3.0" "$dotfile" 2>/dev/null; then
sed -i 's/AGPL-3.0-or-later/MPL-2.0/g; s/AGPL-3.0/MPL-2.0/g' "$dotfile"
FIXES="$FIXES\n- Fixed SPDX header in \`$dotfile\` (AGPL → PMPL)"
FIXES="$FIXES\n- Fixed SPDX header in \`$dotfile\` (AGPL → MPL-2.0)"
CHANGED=true
fi
done
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,8 @@ deps/
.cache/
build/
dist/

# Idris2 proof build artifacts
**/build/
*.ttc
*.ttm
7 changes: 7 additions & 0 deletions .machine_readable/compliance/reuse/dep5
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,10 @@ License: MPL-2.0
Files: cliff.toml
Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}>
License: MPL-2.0

# Documentation prose is CC-BY-SA-4.0 (code/config is MPL-2.0).
# Last-match-wins in the Debian copyright format, so this overrides the
# `Files: *` default above for prose docs.
Files: *.adoc *.md docs/* docs/**/*
Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}>
License: CC-BY-SA-4.0
2 changes: 1 addition & 1 deletion .machine_readable/contractiles/trust/Trustfile.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ is traceable.

### license-content
- description: LICENSE contains expected identifier
- run: grep -q 'PMPL\|MPL\|MIT\|Apache\|LGPL' LICENSE
- run: grep -q 'MPL-2.0' LICENSE
- severity: warning

## Container Security
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ version = "0.1.0"
edition = "2024"
authors = ["Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>"]
description = "Add formal type safety (10 levels, dependent/linear/session types) to any query language — SQL, GraphQL, Cypher, SPARQL, VCL"
license-file = "LICENSE"
license = "MPL-2.0"
repository = "https://github.com/hyperpolymath/typedqliser"
keywords = ["type-safety", "sql", "graphql", "formal-verification", "query"]
categories = ["command-line-utilities", "database"]
Expand Down
2 changes: 2 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
SPDX-License-Identifier: MPL-2.0

Mozilla Public License Version 2.0
==================================

Expand Down
2 changes: 1 addition & 1 deletion QUICKSTART-MAINTAINER.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Or via OPSM: `opsm update {{PACKAGE_NAME}}`

== Security Notes

* License: MPL-2.0 (Palimpsest License)
* License: MPL-2.0 (code) / CC-BY-SA-4.0 (docs)
* All dependencies SHA-pinned
* `panic-attacker` scan results: link:INSTALL-SECURITY-REPORT.adoc[]
* OpenSSF Scorecard: see badge in README
Expand Down
2 changes: 1 addition & 1 deletion contractiles/trust/Trustfile.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Maximal trust by default — LLM may read, build, test, lint, format.

### license-content
- description: LICENSE contains expected SPDX identifier
- run: grep -q 'SPDX\|License\|MIT\|Apache\|PMPL\|MPL' LICENSE
- run: grep -q 'SPDX\|MPL-2.0' LICENSE
- severity: critical

### no-secrets-committed
Expand Down
4 changes: 2 additions & 2 deletions docs/RSR_OUTLINE.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
= RSR Template Repository

image:[Palimpsest-MPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] image:[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"]
image:https://img.shields.io/badge/license-MPL--2.0-blue[MPL-2.0,link="LICENSES/MPL-2.0.txt"] image:https://img.shields.io/badge/docs-CC--BY--SA--4.0-blue[CC-BY-SA-4.0,link="LICENSES/CC-BY-SA-4.0.txt"]
:toc:
:sectnums:

Expand Down Expand Up @@ -78,7 +78,7 @@ just validate-rsr
|Container build (Wolfi base, Podman)

|`LICENSE`
|MPL-2.0 (Palimpsest MPL)
|MPL-2.0 (code) / CC-BY-SA-4.0 (docs)

|`EXHIBIT-A-ETHICAL-USE.txt`
|Ethical use guidelines (LICENSE Exhibit A)
Expand Down
2 changes: 1 addition & 1 deletion docs/STATE-VISUALIZER.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ CONTAINER ECOSYSTEM (Phase 2)

REPO INFRASTRUCTURE
.machine_readable/ ██████████ 100% STATE/META/ECOSYSTEM active
Governance & License ██████████ 100% PMPL & Ethical use verified
Governance & License ██████████ 100% MPL-2.0 & Ethical use verified
Development Shells (Nix/Guix) ██████████ 100% Reproducible env stable

─────────────────────────────────────────────────────────────────────────────
Expand Down
76 changes: 76 additions & 0 deletions src/interface/abi/Typedqliser/ABI/Foreign.idr
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
-- SPDX-License-Identifier: MPL-2.0
-- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
--
||| Foreign Function Interface declarations for TypedQLiser.
|||
||| C-compatible entry points implemented in the Zig FFI layer
||| (src/interface/ffi/src/main.zig). Each safe wrapper maps the raw C result
||| code back to the `Result` type from the ABI.

module Typedqliser.ABI.Foreign

import Typedqliser.ABI.Types
import Typedqliser.ABI.Layout

%default total

||| Initialise the TypedQLiser proof engine; returns a context pointer.
export
%foreign "C:typedqliser_init,libtypedqliser"
prim__init : PrimIO Bits64

export
init : IO (Maybe Handle)
init = do
ptr <- primIO prim__init
pure (createHandle ptr)

||| Release the proof engine context.
export
%foreign "C:typedqliser_free,libtypedqliser"
prim__free : Bits64 -> PrimIO ()

export
free : Handle -> IO ()
free h = primIO (prim__free (handlePtr h))

||| Check a query (null-terminated C string) against a schema, up to the
||| requested level. Returns a C result code.
export
%foreign "C:typedqliser_check_query,libtypedqliser"
prim__checkQuery : Bits64 -> String -> Bits32 -> PrimIO Bits32

export
checkQuery : Handle -> (query : String) -> (level : Bits32) -> IO (Either Result ())
checkQuery h query level = do
rc <- primIO (prim__checkQuery (handlePtr h) query level)
pure $ case rc of
0 => Right ()
2 => Left InvalidQuery
3 => Left SchemaError
_ => Left Error

||| Highest safety level the last checked query achieved (0 if none).
export
%foreign "C:typedqliser_certificate_level,libtypedqliser"
prim__certificateLevel : Bits64 -> PrimIO Bits32

export
certificateLevel : Handle -> IO Nat
certificateLevel h = do
n <- primIO (prim__certificateLevel (handlePtr h))
pure (cast n)

||| Library version string.
export
%foreign "C:typedqliser_version,libtypedqliser"
prim__version : PrimIO Bits64

export
version : IO String
version = do
ptr <- primIO prim__version
pure (prim__getString ptr)
where
%foreign "support:idris2_getString, libidris2_support"
prim__getString : Bits64 -> String
122 changes: 122 additions & 0 deletions src/interface/abi/Typedqliser/ABI/Layout.idr
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
-- SPDX-License-Identifier: MPL-2.0
-- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
--
||| Memory-layout proofs for the TypedQLiser ABI.
|||
||| The proof certificate descriptor crosses the Zig/C FFI boundary; this module
||| pins its field layout and proves it is C-ABI aligned.

module Typedqliser.ABI.Layout

import Typedqliser.ABI.Types
import Data.Vect
import Data.So
import Data.Nat
import Decidable.Equality

%default total

public export
paddingFor : (offset : Nat) -> (alignment : Nat) -> Nat
paddingFor offset alignment =
if offset `mod` alignment == 0
then 0
else minus alignment (offset `mod` alignment)

public export
alignUp : (size : Nat) -> (alignment : Nat) -> Nat
alignUp size alignment = size + paddingFor size alignment

||| `m = k * n` — n divides m.
public export
data Divides : Nat -> Nat -> Type where
DivideBy : (k : Nat) -> {n : Nat} -> {m : Nat} -> (m = k * n) -> Divides n m

||| Sound divisibility decision: returns a real witness when n divides m.
public export
decDivides : (n : Nat) -> (m : Nat) -> Maybe (Divides n m)
decDivides Z _ = Nothing
decDivides (S k) m =
let q = m `div` (S k) in
case decEq m (q * (S k)) of
Yes prf => Just (DivideBy q prf)
No _ => Nothing

public export
record Field where
constructor MkField
name : String
offset : Nat
size : Nat
alignment : Nat

public export
record StructLayout where
constructor MkStructLayout
fields : Vect k Field
totalSize : Nat
alignment : Nat
{auto 0 sizeCorrect : So (totalSize >= sum (map (\f => f.size) fields))}
{auto 0 aligned : Divides alignment totalSize}

||| The proof-certificate descriptor as it crosses the FFI (40 bytes, 8-aligned).
public export
certificateDescLayout : StructLayout
certificateDescLayout =
MkStructLayout
[ MkField "query_hash_ptr" 0 8 8
, MkField "schema_ver_ptr" 8 8 8
, MkField "max_level" 16 4 4
, MkField "num_proofs" 20 4 4
, MkField "proofs_ptr" 24 8 8
, MkField "result_code" 32 4 4
, MkField "padding" 36 4 4
]
40
8
{sizeCorrect = Oh}
{aligned = DivideBy 5 Refl}

||| Every field offset in a layout is correctly aligned.
public export
data FieldsAligned : Vect len Field -> Type where
NoFields : FieldsAligned []
ConsField :
(f : Field) ->
(rest : Vect len Field) ->
Divides f.alignment f.offset ->
FieldsAligned rest ->
FieldsAligned (f :: rest)

||| Decide field alignment, building a real witness from per-field divisibility.
public export
decFieldsAligned : (fs : Vect len Field) -> Maybe (FieldsAligned fs)
decFieldsAligned [] = Just NoFields
decFieldsAligned (f :: fs) =
case decDivides f.alignment f.offset of
Nothing => Nothing
Just dvd => case decFieldsAligned fs of
Nothing => Nothing
Just rest => Just (ConsField f fs dvd rest)

public export
data CABICompliant : StructLayout -> Type where
CABIOk : (layout : StructLayout) -> FieldsAligned layout.fields -> CABICompliant layout

||| Verify a layout against the C-ABI alignment rules; real proof or error.
public export
checkCABI : (layout : StructLayout) -> Either String (CABICompliant layout)
checkCABI layout =
case decFieldsAligned layout.fields of
Just prf => Right (CABIOk layout prf)
Nothing => Left "Field offsets are not correctly aligned for the C ABI"

||| Decide whether a field lies within a struct's byte bounds (honest Maybe;
||| the property is false for an arbitrary field, so it is decided not asserted).
public export
offsetInBounds : (layout : StructLayout) -> (f : Field) ->
Maybe (So (f.offset + f.size <= layout.totalSize))
offsetInBounds layout f =
case choose (f.offset + f.size <= layout.totalSize) of
Left ok => Just ok
Right _ => Nothing
Loading
Loading