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
4 changes: 4 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<!--
SPDX-License-Identifier: MPL-2.0
Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
-->
# Formatrix Docs - Claude Code Instructions

## Project Overview
Expand Down
34 changes: 34 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# SPDX-License-Identifier: MPL-2.0
# CODEOWNERS - Define code review assignments for GitHub
# See: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

# Default: sole maintainer for all files
* @hyperpolymath

# Security-sensitive files require explicit ownership
SECURITY.md @hyperpolymath
.github/workflows/ @hyperpolymath
.machine_readable/ @hyperpolymath
contractiles/ @hyperpolymath

# License files
LICENSE @hyperpolymath
LICENSES/ @hyperpolymath

# Configuration
.gitignore @hyperpolymath
.github/ @hyperpolymath

# Documentation
README* @hyperpolymath
CONTRIBUTING* @hyperpolymath
CODE_OF_CONDUCT* @hyperpolymath
GOVERNANCE* @hyperpolymath
MAINTAINERS* @hyperpolymath
CHANGELOG* @hyperpolymath
ROADMAP* @hyperpolymath

# Build and CI
Justfile @hyperpolymath
Makefile @hyperpolymath
*.sh @hyperpolymath
6 changes: 6 additions & 0 deletions .github/copilot/coding-agent.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
mcp_servers:
boj-server:
command: npx
args: ["-y", "@hyperpolymath/boj-server@latest"]
env:
BOJ_URL: http://localhost:7700
2 changes: 2 additions & 0 deletions .github/workflows/boj-build.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# // Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
# SPDX-License-Identifier: MPL-2.0
name: BoJ Server Build Trigger
on:
Expand All @@ -7,6 +8,7 @@ on:
jobs:
trigger-boj:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
Expand Down
15 changes: 3 additions & 12 deletions .github/workflows/casket-pages.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,34 @@
# // Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
# SPDX-License-Identifier: MPL-2.0-or-later
name: GitHub Pages

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4

- name: Checkout casket-ssg
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
with:
repository: hyperpolymath/casket-ssg
path: .casket-ssg

- name: Setup GHCup
uses: haskell-actions/setup@f9150cb1d140e9a9271700670baa38991e6fa25c # v2
with:
ghc-version: '9.8.2'
cabal-version: '3.10'

- name: Cache Cabal
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
Expand All @@ -42,11 +37,9 @@ jobs:
~/.cabal/store
.casket-ssg/dist-newstyle
key: ${{ runner.os }}-casket-${{ hashFiles('.casket-ssg/casket-ssg.cabal') }}

- name: Build casket-ssg
working-directory: .casket-ssg
run: cabal build

- name: Build site
run: |
mkdir -p site _site
Expand Down Expand Up @@ -77,20 +70,18 @@ jobs:
fi
fi
cd .casket-ssg && cabal run casket-ssg -- build ../site ../_site

- name: Setup Pages
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5

- name: Upload artifact
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
with:
path: '_site'

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
timeout-minutes: 15
needs: build
steps:
- name: Deploy to GitHub Pages
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/cflite_batch.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# // Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
# SPDX-License-Identifier: MPL-2.0
name: ClusterFuzzLite Batch
on:
Expand All @@ -8,6 +9,7 @@ permissions:
jobs:
BatchFuzzing:
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/cflite_pr.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# // Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
# SPDX-License-Identifier: MPL-2.0
name: ClusterFuzzLite PR
on:
Expand All @@ -9,6 +10,7 @@ permissions:
jobs:
PR:
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
Expand Down
11 changes: 3 additions & 8 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
# SPDX-License-Identifier: PMPL-1.0
# // Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
# SPDX-License-Identifier: MPL-2.0
name: CodeQL Security Analysis

on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
schedule:
- cron: '0 6 * * 1'

# 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:
analyze:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
security-events: write
Expand All @@ -32,17 +30,14 @@ jobs:
include:
- language: javascript-typescript
build-mode: none

steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Initialize CodeQL
uses: github/codeql-action/init@c6f931105cb2c34c8f901cc885ba1e2e259cf745 # v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@c6f931105cb2c34c8f901cc885ba1e2e259cf745 # v3
with:
Expand Down
29 changes: 5 additions & 24 deletions .github/workflows/dogfood-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,24 @@
# Validates that the repo uses hyperpolymath's own formats and tools.
# Companion to static-analysis-gate.yml (security) — this is for format compliance.
name: Dogfood Gate

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

permissions:
contents: read

jobs:
# ---------------------------------------------------------------------------
# Job 1: A2ML manifest validation
# ---------------------------------------------------------------------------
a2ml-validate:
name: Validate A2ML manifests
runs-on: ubuntu-latest

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

- name: Check for A2ML files
id: detect
run: |
Expand All @@ -35,14 +31,12 @@ jobs:
if [ "$COUNT" -eq 0 ]; then
echo "::warning::No .a2ml manifest files found. Every RSR repo should have 0-AI-MANIFEST.a2ml"
fi

- name: Validate A2ML manifests
if: steps.detect.outputs.count > 0
uses: hyperpolymath/a2ml-validate-action@6bff6ec134fc977e86d25166a5c522ddea5c1e78 # main
with:
path: '.'
strict: 'false'

- name: Write summary
run: |
A2ML_COUNT="${{ steps.detect.outputs.count }}"
Expand All @@ -59,18 +53,16 @@ jobs:
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Scanned **${A2ML_COUNT}** .a2ml file(s). See step output for details." >> "$GITHUB_STEP_SUMMARY"
fi

# ---------------------------------------------------------------------------
# Job 2: K9 contract validation
# ---------------------------------------------------------------------------
k9-validate:
name: Validate K9 contracts
runs-on: ubuntu-latest

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

- name: Check for K9 files
id: detect
run: |
Expand All @@ -83,14 +75,12 @@ jobs:
if [ "$COUNT" -eq 0 ] && [ "$CONFIG_COUNT" -gt 0 ]; then
echo "::warning::Found $CONFIG_COUNT config files but no K9 contracts. Run k9iser to generate contracts."
fi

- name: Validate K9 contracts
if: steps.detect.outputs.k9_count > 0
uses: hyperpolymath/k9-validate-action@2d96f43c538964b097d159ed3a56ba5b5ceca227 # main
with:
path: '.'
strict: 'false'

- name: Write summary
run: |
K9_COUNT="${{ steps.detect.outputs.k9_count }}"
Expand All @@ -108,18 +98,16 @@ jobs:
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Validated **${K9_COUNT}** K9 contract(s) against **${CFG_COUNT}** config file(s)." >> "$GITHUB_STEP_SUMMARY"
fi

# ---------------------------------------------------------------------------
# Job 3: Empty-linter — invisible character detection
# ---------------------------------------------------------------------------
empty-lint:
name: Empty-linter (invisible characters)
runs-on: ubuntu-latest

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

- name: Scan for invisible characters
id: lint
run: |
Expand Down Expand Up @@ -153,7 +141,6 @@ jobs:
REL_PATH="${filepath#$GITHUB_WORKSPACE/}"
echo "::warning file=${REL_PATH}::Invisible Unicode characters detected (zero-width space, BOM, NBSP, etc.)"
done < /tmp/empty-lint-results.txt

- name: Write summary
run: |
if [ "${{ steps.lint.outputs.ready }}" = "true" ]; then
Expand All @@ -172,18 +159,16 @@ jobs:
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Skipped: empty-linter not available." >> "$GITHUB_STEP_SUMMARY"
fi

# ---------------------------------------------------------------------------
# Job 4: Groove manifest check (for repos that should expose services)
# ---------------------------------------------------------------------------
groove-check:
name: Groove manifest check
runs-on: ubuntu-latest

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

- name: Check for Groove manifest
id: groove
run: |
Expand Down Expand Up @@ -220,7 +205,6 @@ jobs:
if [ "$HAS_SERVER" = "true" ] && [ "$HAS_MANIFEST" = "false" ] && [ "$HAS_GROOVE_CODE" = "false" ]; then
echo "::warning::This repo has server code but no Groove endpoint. Add .well-known/groove/manifest.json for service discovery."
fi

- name: Write summary
run: |
echo "## Groove Protocol Check" >> "$GITHUB_STEP_SUMMARY"
Expand All @@ -230,20 +214,18 @@ jobs:
echo "| Static manifest (.well-known/groove/manifest.json) | ${{ steps.groove.outputs.has_manifest }} |" >> "$GITHUB_STEP_SUMMARY"
echo "| Groove endpoint in code | ${{ steps.groove.outputs.has_groove_code }} |" >> "$GITHUB_STEP_SUMMARY"
echo "| Has HTTP server code | ${{ steps.groove.outputs.has_server }} |" >> "$GITHUB_STEP_SUMMARY"

# ---------------------------------------------------------------------------
# Job 5: Dogfooding summary
# ---------------------------------------------------------------------------
dogfood-summary:
name: Dogfooding compliance summary
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [a2ml-validate, k9-validate, empty-lint, groove-check]
if: always()

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

- name: Generate dogfooding scorecard
run: |
SCORE=0
Expand Down Expand Up @@ -306,4 +288,3 @@ jobs:
*Generated by the [Dogfood Gate](https://github.com/hyperpolymath/rsr-template-repo) workflow.*
*Dogfooding is guinea pig fooding — we test our tools on ourselves.*
EOF

Loading
Loading