diff --git a/.github/workflows/code-hygiene-self-test.yml b/.github/workflows/code-hygiene-self-test.yml index 907c789..a90ea23 100644 --- a/.github/workflows/code-hygiene-self-test.yml +++ b/.github/workflows/code-hygiene-self-test.yml @@ -9,6 +9,7 @@ on: - 'actions/referencing-check/**' - 'actions/secrets-check/**' - 'actions/boj-cartridge-check/**' + - 'actions/manifest-check/**' - '.github/workflows/code-hygiene-self-test.yml' pull_request: paths: @@ -17,6 +18,7 @@ on: - 'actions/referencing-check/**' - 'actions/secrets-check/**' - 'actions/boj-cartridge-check/**' + - 'actions/manifest-check/**' - '.github/workflows/code-hygiene-self-test.yml' permissions: @@ -39,3 +41,37 @@ jobs: - run: bash actions/referencing-check/test.sh - run: bash actions/secrets-check/test.sh - run: bash actions/boj-cartridge-check/test.sh + - name: Create manifest controls + id: fixtures + shell: bash + run: | + root="$RUNNER_TEMP/manifest-controls" + mkdir -p "$root/valid" "$root/bad-a2ml" "$root/bad-k9" + printf '%s\n' '# SPDX-License-Identifier: MPL-2.0' 'agent-id = "ci-control"' 'version = "1.0.0"' > "$root/valid/control.a2ml" + printf '%s\n' 'K9!' '# SPDX-License-Identifier: MPL-2.0' 'pedigree = {' ' metadata = { name = "ci-control", version = "1.0.0" },' " security = { leash = 'Kennel }," '}' > "$root/valid/control.k9.ncl" + printf '%s\n' 'invalid manifest' > "$root/bad-a2ml/control.a2ml" + # K9-suffixed library modules are outside pedigree validation. Give + # this negative control a real contract marker and omit its pedigree. + printf '%s\n' 'K9!' '# SPDX-License-Identifier: MPL-2.0' 'invalid manifest' > "$root/bad-k9/control.k9.ncl" + echo "root=$root" >> "$GITHUB_OUTPUT" + - name: Valid manifests must pass + uses: ./actions/manifest-check + with: + path: ${{ steps.fixtures.outputs.root }}/valid + - name: Invalid A2ML must fail + id: bad-a2ml + continue-on-error: true + uses: ./actions/manifest-check + with: + path: ${{ steps.fixtures.outputs.root }}/bad-a2ml + - name: Invalid K9 Nickel manifest must fail + id: bad-k9 + continue-on-error: true + uses: ./actions/manifest-check + with: + path: ${{ steps.fixtures.outputs.root }}/bad-k9 + - name: Verify both negative controls failed + env: + A2ML_OUTCOME: ${{ steps.bad-a2ml.outcome }} + K9_OUTCOME: ${{ steps.bad-k9.outcome }} + run: test "$A2ML_OUTCOME" = failure && test "$K9_OUTCOME" = failure diff --git a/actions/manifest-check/action.yml b/actions/manifest-check/action.yml index 1f668db..75c14be 100755 --- a/actions/manifest-check/action.yml +++ b/actions/manifest-check/action.yml @@ -1,27 +1,28 @@ +# SPDX-License-Identifier: MPL-2.0 name: 'Manifest Validation Gate' -description: 'Strict parsing of .a2ml and .k9 files to guarantee they align with grammars and are fully populated.' +description: 'Validate A2ML/DEED and K9 manifest structure using the maintained format validators.' +inputs: + path: + description: 'Directory containing manifests to validate.' + required: false + default: '.' + strict: + description: 'Promote validator warnings to failures.' + required: false + default: 'false' runs: using: 'composite' steps: - - name: Run Manifest Check - shell: bash - run: | - echo "Validating A2ML and K9 manifests..." - - # We would use the a2ml-tool or k9-validate here - manifests=$(find . -name "*.a2ml" -o -name "*.k9" 2>/dev/null) - if [ -n "$manifests" ]; then - for m in $manifests; do - echo "Checking $m..." - # Check for unpopulated null points - if grep -qE '""|\[\]|\{\}|null' "$m"; then - echo "::warning::Manifest $m contains empty or null points. Ensure it is fully populated with explicit values or null markers." - fi - - # Placeholder for actual parser invocation - # a2ml-tool validate "$m" || exit 1 - done - echo "Manifest validation passed." - else - echo "No .a2ml or .k9 manifests found." - fi + - name: Validate A2ML and DEED manifests + uses: hyperpolymath/deed-ecosystem/validate-action@f7a40a4d5cc82b2e73f861119baa6818d77a448d + with: + path: ${{ inputs.path }} + strict: ${{ inputs.strict }} + - name: Validate K9 manifests + uses: hyperpolymath/k9-ecosystem/validate-action@2ee51eed590b4722efcdca2fe4685ef24600bced + with: + path: ${{ inputs.path }} + strict: ${{ inputs.strict }} +# These validators check manifest structure. Executable Nickel contracts need +# a separate Nickel evaluation step; neither an empty-field grep nor this +# structural check establishes that a contract evaluates or a proof holds.