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
26 changes: 11 additions & 15 deletions .github/scripts/validate-a2ml.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
# SPDX-License-Identifier: PMPL-1.0-or-later
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
#
# Vendored from hyperpolymath/a2ml-validate-action @ 86c6da6 (#8), with one
# repair: upstream had a stray newline splitting a comment ("# own \name/...")
# so `ame/project` ran as a command and aborted the script under `set -e`.
# The action SHA this repo previously pinned predated the typed-manifest /
# contractile-shape identity exemptions. Re-adopt the upstream action once
# its HEAD is fixed.
#
# validate-a2ml.sh — A2ML manifest validation script
#
# Scans for .a2ml files and validates:
Expand Down Expand Up @@ -127,14 +134,12 @@ validate_a2ml() {
while IFS= read -r line; do
line_num=$((line_num + 1))

# Check for identity fields (various A2ML patterns). Accept TOML
# (`key = …`) and YAML-flavoured (`key: …`) forms, and the
# canonical-/prefixed-name + id keys used by clade/anchor docs.
if [[ "$line" =~ ^[[:space:]]*(agent[-_]id|name|project|id|canonical-name|prefixed-name)[[:space:]]*[=:] ]]; then
# Check for identity fields (various A2ML patterns)
if [[ "$line" =~ ^[[:space:]]*(agent[-_]id|name|project)[[:space:]]*= ]]; then
has_identity=true
fi
# Check for version field (TOML or YAML form)
if [[ "$line" =~ ^[[:space:]]*(version|schema_version)[[:space:]]*[=:] ]]; then
# Check for version field
if [[ "$line" =~ ^[[:space:]]*(version|schema_version)[[:space:]]*= ]]; then
has_version=true
fi
done < "$file"
Expand Down Expand Up @@ -162,15 +167,6 @@ validate_a2ml() {
;;
esac

# Path-identified instruction docs under .machine_readable/agent_instructions/
# (coverage/debt/methodology…) derive identity from directory + filename,
# like the 6a2 typed manifests, and carry only a [metadata] version block.
case "$file" in
*/.machine_readable/agent_instructions/*.a2ml)
is_manifest=true
;;
esac

# Contractile-shape A2ML files use `@directive:` syntax instead of
# TOML `key = value`. Trustfile.a2ml, Intentfile.a2ml, Mustfile.a2ml,
# Adjustfile.a2ml etc. are policy / trust / intent / abstract files
Expand Down
26 changes: 14 additions & 12 deletions .github/workflows/dogfood-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,27 @@ jobs:
# recognises the clade/anchor/agent-instruction identity shapes.
- name: Validate A2ML manifests
if: steps.detect.outputs.count > 0
uses: hyperpolymath/a2ml-validate-action@fd7b2d840449568867f88cc93f64a9b3db1e2153 # contractile-shape carve-out (#9)
with:
path: '.'
strict: 'false'
# Defaults (pinned action fd7b2d8 has no built-in default for this
# input) plus two files that declare their identity in a non-TOML
# A2ML dialect the pinned validator's `key =` regex cannot see:
# ANCHOR.a2ml uses `id: "..."` and Bustfile.a2ml a curly block
# with `name: "..."`. They are valid, just a different doc shape.
paths-ignore: |
shell: bash
env:
INPUT_PATH: '.'
INPUT_STRICT: 'false'
# Default carve-outs plus stapeln's legitimately distinct A2ML
# doc-types whose identity is structural, not a TOML name/version
# pair: clade declarations, YAML anchor files, and agent-instruction
# session configs. Same rationale as the action's built-in defaults
# (hyperpolymath/hypatia#243 — distinguish doc type from target).
INPUT_PATHS_IGNORE: |
vendor/
vendored/
verified-container-spec/
.audittraining/
integration/fixtures/
test/fixtures/
tests/fixtures/
anchors/ANCHOR.a2ml
contractiles/bust/Bustfile.a2ml
.machine_readable/agent_instructions/
.machine_readable/CLADE.a2ml
.machine_readable/anchors/
run: .github/scripts/validate-a2ml.sh

- name: Write summary
run: |
Expand Down
17 changes: 11 additions & 6 deletions .github/workflows/hypatia-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,12 @@ jobs:
continue-on-error: true
uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 # v1.18.2
with:
elixir-version: '1.19.4'
otp-version: '28.3'
# Hypatia's mix.exs requires `elixir ~> 1.14`. The previous pins
# (Elixir 1.19.4 / OTP 28.3) are not in setup-beam's version index,
# so the step failed in ~15s before any scan ran. Use known-good
# stable lines; major.minor lets setup-beam pick the latest patch.
elixir-version: '1.17'
otp-version: '27'

- name: Clone Hypatia
continue-on-error: true
Expand All @@ -59,12 +63,13 @@ jobs:
continue-on-error: true
working-directory: ${{ env.HOME }}/hypatia
run: |
if [ ! -f hypatia-v2 ]; then
echo "Building hypatia-v2 scanner..."
cd scanner
# The Hypatia mix project lives at the repo root (there is no
# scanner/ subdirectory). escript.build emits ./hypatia, which
# hypatia-cli.sh prefers (hypatia-v2 is only a legacy fallback).
if [ ! -x hypatia ] && [ ! -x hypatia-v2 ]; then
echo "Building hypatia escript..."
mix deps.get
mix escript.build
mv hypatia ../hypatia-v2
fi

# No explicit build step: hypatia-cli.sh self-builds the escript
Expand Down
28 changes: 12 additions & 16 deletions .github/workflows/secret-scanner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,18 @@ jobs:
with:
fetch-depth: 0 # Full history for scanning

# The trufflehog GitHub Action runs in git-diff mode and exits non-zero
# with "BASE and HEAD commits are the same" on several event shapes
# (fresh branch push, single-commit PR), failing the job even when no
# secret exists. Invoke the pinned CLI directly for a deterministic
# full-history scan that only fails on a *verified* finding.
- name: TruffleHog Secret Scan
uses: trufflesecurity/trufflehog@37b77001d0174ebec2fcca2bd83ff83a6d45a3ab # v3.95.3
with:
# Scan the full checked-out history (fetch-depth: 0 above) rather
# than an event-derived base..head range. The old pin failed every
# run with "BASE and HEAD commits are the same" on push-to-main and
# on PRs (empty/degenerate diff range) — a wrapper bug, not a real
# finding (a full-tree scan reports zero secrets). An empty `base`
# makes the scan deterministic and only fails on verified secrets.
base: ""
extra_args: --only-verified
# The trufflehog GitHub Action wraps a Docker range-scan
# (--since-commit BASE --branch HEAD against :latest) that fails on PRs
# even when there are zero secrets. A full-history filesystem scan is
# deterministic and is the mode actually intended here. Version pinned
# for reproducibility.
- name: Install TruffleHog
run: |
curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
| sh -s -- -b /usr/local/bin v3.95.3

- name: TruffleHog Secret Scan (full history)
run: trufflehog git "file://$GITHUB_WORKSPACE" --only-verified --fail --no-update

gitleaks:
runs-on: ubuntu-latest
Expand Down
5 changes: 4 additions & 1 deletion container-stack/vordr/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
# artefacts and are NOT shipped in the container image.

# ── Stage 1: Build ────────────────────────────────────────────────
FROM rust:1.83-slim AS rust-builder
# Rust >= 1.86 is required: the pinned Cargo.lock resolves icu_* 2.2.0 /
# idna_adapter 1.2.2 (MSRV 1.86) and indexmap 2.14.0 (Cargo edition2024,
# needs Cargo >= 1.85). Older toolchains fail at manifest parse time.
FROM rust:1.86-slim AS rust-builder

RUN apt-get update && apt-get install -y --no-install-recommends \
pkg-config libsqlite3-dev ca-certificates \
Expand Down
Loading