diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index 6918389..a392c98 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -22,7 +22,7 @@ jobs: # --------------------------------------------------------------------------- a2ml-validate: name: Validate A2ML manifests - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout repository @@ -66,7 +66,7 @@ jobs: # --------------------------------------------------------------------------- k9-validate: name: Validate K9 contracts - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout repository @@ -115,7 +115,7 @@ jobs: # --------------------------------------------------------------------------- empty-lint: name: Empty-linter (invisible characters) - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout repository @@ -179,7 +179,7 @@ jobs: # --------------------------------------------------------------------------- groove-check: name: Groove manifest check - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout repository @@ -237,7 +237,7 @@ jobs: # --------------------------------------------------------------------------- eclexiaiser-validate: name: Validate eclexiaiser manifest - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout repository @@ -257,28 +257,34 @@ jobs: echo "has_manifest=true" >> "$GITHUB_OUTPUT" - # Validate TOML structure using Python 3.11+ tomllib - python3 -c " - import tomllib, sys - with open('eclexiaiser.toml', 'rb') as f: - data = tomllib.load(f) - project = data.get('project', {}) - if not project.get('name', '').strip(): - print('ERROR: project.name is required', file=sys.stderr) - sys.exit(1) - functions = data.get('functions', []) - if not functions: - print('ERROR: at least one [[functions]] entry is required', file=sys.stderr) - sys.exit(1) - for fn in functions: - if not fn.get('name', '').strip(): - print('ERROR: function name cannot be empty', file=sys.stderr) - sys.exit(1) - if not fn.get('source', '').strip(): - print(f'ERROR: function {fn[\"name\"]} has no source path', file=sys.stderr) - sys.exit(1) - print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))') - " || { + # Validate TOML structure using pre-installed yq + ( + PROJECT_NAME=$(yq -e '.project.name // ""' eclexiaiser.toml) + if [ -z "$PROJECT_NAME" ]; then + echo "ERROR: project.name is required" >&2 + exit 1 + fi + + FUNCTIONS_LEN=$(yq -e '.functions | length' eclexiaiser.toml) + if [ -z "$FUNCTIONS_LEN" ] || [ "$FUNCTIONS_LEN" -eq 0 ]; then + echo "ERROR: at least one [[functions]] entry is required" >&2 + exit 1 + fi + + for i in $(seq 0 $((FUNCTIONS_LEN - 1))); do + FN_NAME=$(yq -e ".functions[$i].name // \"\"" eclexiaiser.toml) + if [ -z "$FN_NAME" ]; then + echo "ERROR: function name cannot be empty" >&2 + exit 1 + fi + FN_SRC=$(yq -e ".functions[$i].source // \"\"" eclexiaiser.toml) + if [ -z "$FN_SRC" ]; then + echo "ERROR: function $FN_NAME has no source path" >&2 + exit 1 + fi + done + echo "Valid: $PROJECT_NAME ($FUNCTIONS_LEN function(s))" + ) || { echo "::error file=eclexiaiser.toml::Invalid eclexiaiser.toml — see step output for details" exit 1 } @@ -300,7 +306,7 @@ jobs: # --------------------------------------------------------------------------- dogfood-summary: name: Dogfooding compliance summary - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: [a2ml-validate, k9-validate, empty-lint, groove-check, eclexiaiser-validate] if: always() diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index b3e0ff0..cd592b2 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -16,10 +16,7 @@ concurrency: # at plan time with zero jobs. permissions: contents: read - pull-requests: write - actions: read - jobs: scan: - uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@a44c93a5cd3d293ee3e8b488444dcdc19c4e5d49 + uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@db12a6ad3ef9076d5f7bdcf98d7d15cf8547555a secrets: inherit diff --git a/.machine_readable/svc/k9/methodology-guard.k9.ncl b/.machine_readable/svc/k9/methodology-guard.k9.ncl index 255ed61..d3bf70e 100644 --- a/.machine_readable/svc/k9/methodology-guard.k9.ncl +++ b/.machine_readable/svc/k9/methodology-guard.k9.ncl @@ -1,3 +1,4 @@ +K9! # SPDX-License-Identifier: MPL-2.0 # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # diff --git a/.mise.toml b/.mise.toml new file mode 100644 index 0000000..a352423 --- /dev/null +++ b/.mise.toml @@ -0,0 +1,11 @@ +[tools] +# = "Uncomment and customize for your project" +# = "rust nightly" +# = "just 1.40.0" +# = "nickel 1.10.0" +# = "gleam 1.8.0" +# = "elixir 1.18.0" +# = "erlang 27.2" +# = "zig 0.14.0" +# = "idris2 0.7.0" +rust = "nightly" diff --git a/.tool-versions b/.tool-versions deleted file mode 100644 index ce60c32..0000000 --- a/.tool-versions +++ /dev/null @@ -1,10 +0,0 @@ -# Uncomment and customize for your project -# rust nightly -# just 1.40.0 -# nickel 1.10.0 -# gleam 1.8.0 -# elixir 1.18.0 -# erlang 27.2 -# zig 0.14.0 -# idris2 0.7.0 -rust nightly diff --git a/container/deploy.k9.ncl b/container/deploy.k9.ncl index a85d1fa..aff8a0f 100644 --- a/container/deploy.k9.ncl +++ b/container/deploy.k9.ncl @@ -1,3 +1,4 @@ +K9! # SPDX-License-Identifier: MPL-2.0 # deploy.k9.ncl — Patch Bridge deployment component (Hunt level) #