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
8 changes: 7 additions & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ jobs:
fail-fast: false
matrix:
include:
- language: javascript-typescript
# Repo source is Rust + Zig (neither natively supported by
# CodeQL extractors that we use). Scan workflow files via the
# `actions` extractor instead — every repo has those, and
# this avoids the "no source files" false-failure that the
# `javascript-typescript` default produced. See hypatia rule
# `codeql_language_matrix_mismatch`.
- language: actions
build-mode: none

steps:
Expand Down
36 changes: 26 additions & 10 deletions .github/workflows/k9-svc-validation.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,43 @@
# SPDX-License-Identifier: MPL-2.0
name: K9-SVC Validation
on: [push, pull_request]

on:
push:
branches: [main, master]
pull_request:

# Estate guardrail: cancel superseded runs so re-pushes / rebased PR
# updates do not pile up queued runs against the shared account-wide
# Actions concurrency pool. Applied only to read-only check workflows
# (no publish/mutation), so cancelling a superseded run is always safe.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Validate contractiles
run: |
#!/bin/bash
set -euo
#!/usr/bin/env bash
set -euo pipefail

# Check all contractiles exist
for file in must trust dust lust adjust intend; do
if [ ! -f ".machine_readable/contractiles/$file/${file}file.a2ml" ]; then
echo "ERROR: Missing contractile: $file"
exit 1
fi
done
echo "✓ All contractiles present"

echo "OK: all contractiles present"

# Basic syntax validation
find .machine_readable/contractiles -name "*.a2ml" -exec grep -l "SPDX-License-Identifier" {} \; | wc -l
echo "✓ Contractile validation passed"

echo "OK: contractile validation passed"
64 changes: 6 additions & 58 deletions .github/workflows/rust-ci.yml
Original file line number Diff line number Diff line change
@@ -1,69 +1,17 @@
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
#
# rust-ci.yml — Cargo build, test, clippy, and fmt for Rust projects.
# Only runs if Cargo.toml exists in the repo root.
# Rust CI — thin wrapper calling the shared estate reusable in
# hyperpolymath/standards. Configure once, propagate everywhere.
# See: docs/CI-REUSABLE-WORKFLOWS.adoc in standards.
name: Rust CI

on:
pull_request:
branches: ['**']
push:
branches: [main, master]
pull_request:

permissions:
contents: read

jobs:
check:
name: Cargo check + clippy + fmt
runs-on: ubuntu-latest
if: hashFiles('Cargo.toml') != ''

steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
with:
components: clippy, rustfmt

- name: Cache cargo registry and build
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2

- name: Cargo check
run: cargo check --all-targets 2>&1

- name: Cargo fmt
run: cargo fmt --all -- --check

- name: Cargo clippy
run: cargo clippy --all-targets -- -D warnings

test:
name: Cargo test
runs-on: ubuntu-latest
needs: check
if: hashFiles('Cargo.toml') != ''

steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable

- name: Cache cargo registry and build
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2

- name: Run tests
run: cargo test --all-targets

- name: Write summary
if: always()
run: |
echo "## Rust CI Results" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "- **cargo check**: passed" >> "$GITHUB_STEP_SUMMARY"
echo "- **cargo test**: completed" >> "$GITHUB_STEP_SUMMARY"
rust-ci:
uses: hyperpolymath/standards/.github/workflows/rust-ci-reusable.yml@4fdf4314b4ab54269adbaff10e30e483b5e86845
129 changes: 129 additions & 0 deletions examples/SafeDOMExample.affine
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// SPDX-License-Identifier: MPL-2.0
// SafeDOMExample.affine — formally-verified DOM mounting (aspirational).
//
// This example shows the *shape* of SafeDOM consumer code in current
// AffineScript syntax. The `SafeDOM` stdlib surface it references
// (`mount_safe`, `mount_when_ready`, `mount_batch`,
// `proven_selector_validate`, `proven_html_validate`, `mount`) is the
// target of `affinescript#56` (DOM+Pixi binding survey) and does not
// yet exist in the published stdlib. The file is therefore
// parse-checked but not type-checked end-to-end until #56 lands the
// bindings; `affinescript check` reports `Resolve.UndefinedModule
// SafeDOM` which is expected.
//
// Previous versions of this file (estate-wide, 5 dialect variants)
// pre-dated ADR-014 (qualified paths), ADR-016 (effect rows), and the
// `#{`-record-literal sigil (ADR-215). They were retired in favour of
// this canonical via the gitbot-fleet#208 sweep (2026-05-26).

module SafeDOMExample;

use prelude::{Option, Some, None, Result, Ok, Err};

// `Element` and friends are nominal extern types for now — the real
// shape lands with affinescript#56.
extern type Element;
extern type Selector;
extern type ValidHTML;

// Single-mount status, lifted from the host into a typed tag union.
enum MountStatus {
Mounted(Element),
MountPointNotFound(String),
InvalidSelector(String),
InvalidHTML(String)
}

// Batch-mount result.
enum MountResult {
Mounted([Element]),
Failed(String)
}

// Spec for one element in a batch mount.
struct MountSpec {
selector: String,
html: String
}

// SafeDOM's host-side surface, all IO-effecting. Callbacks are passed
// as separate parameters (rather than a `MountCallbacks` record)
// because fn-typed struct fields are not currently parser-supported.
extern fn mount_safe(
selector: ref String,
html: ref String,
on_success: fn(Element) -> (),
on_error: fn(String) -> (),
) -{IO}-> ();

extern fn mount_when_ready(
selector: ref String,
html: ref String,
on_success: fn(Element) -> (),
on_error: fn(String) -> (),
) -{IO}-> ();

extern fn mount_batch(specs: ref [MountSpec]) -{IO}-> MountResult;

extern fn proven_selector_validate(s: ref String) -{IO}-> Result<Selector, String>;
extern fn proven_html_validate(s: ref String) -{IO}-> Result<ValidHTML, String>;
extern fn mount(sel: ref Selector, html: ref ValidHTML) -{IO}-> MountStatus;

extern fn array_for_each(xs: ref [Element], f: fn(Element) -> ()) -{IO}-> ();
extern fn array_len(xs: ref [Element]) -> Int;

// Example 1 — basic mount with success/error branches.
pub fn mount_app() -{IO}-> () {
mount_safe(
"#app",
"<div><h1>Hello, World!</h1><p>Mounted safely with proofs.</p></div>",
fn(el) -> () { Console::log("App mounted successfully"); },
fn(err) -> () { Console::error("Mount failed: " ++ err); },
);
}

// Example 2 — defer until DOM ready.
pub fn mount_when_dom_ready() -{IO}-> () {
mount_when_ready(
"#app",
"<div class='container'><h1>App Title</h1></div>",
fn(_el) -> () { Console::log("Mounted after DOM ready"); },
fn(err) -> () { Console::error("Failed: " ++ err); },
);
}

// Example 3 — atomic batch mount.
pub fn mount_multiple() -{IO}-> () {
let specs = [
MountSpec #{ selector: "#header", html: "<header><h1>Site Title</h1></header>" },
MountSpec #{ selector: "#nav", html: "<nav><a href='/'>Home</a></nav>" },
MountSpec #{ selector: "#main", html: "<main><p>Content here</p></main>" },
MountSpec #{ selector: "#footer", html: "<footer>2026</footer>" },
];

match mount_batch(specs) {
Mounted(elements) => {
Console::log("Batch mount succeeded");
array_for_each(elements, fn(_el) -> () { Console::log(" element"); });
},
Failed(err) => {
Console::error("Batch mount failed (atomic — none mounted): " ++ err);
}
}
}

// Example 4 — explicit two-stage validation before mounting.
pub fn mount_with_validation() -{IO}-> () {
match proven_selector_validate("#my-app") {
Err(e) => Console::error("Invalid selector: " ++ e),
Ok(valid_selector) => match proven_html_validate("<div>Content</div>") {
Err(e) => Console::error("Invalid HTML: " ++ e),
Ok(valid_html) => match mount(valid_selector, valid_html) {
Mounted(_el) => Console::log("Mounted with validated inputs"),
MountPointNotFound(s) => Console::error("Element not found: " ++ s),
InvalidSelector(_) => Console::error("impossible — already validated"),
InvalidHTML(_) => Console::error("impossible — already validated"),
},
},
}
}
109 changes: 0 additions & 109 deletions examples/SafeDOMExample.res

This file was deleted.

Loading