diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2132109..65789e9 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -29,9 +29,9 @@ Copyright (c) Jonathan D.A. Jewell ### As Applicable -- [ ] `.machine_readable/STATE.a2ml` updated (if project state changed) -- [ ] `.machine_readable/ECOSYSTEM.a2ml` updated (if integrations changed) -- [ ] `.machine_readable/META.a2ml` updated (if architectural decisions changed) +- [ ] `.machine_readable/descriptiles/STATE.a2ml` updated (if project state changed) +- [ ] `.machine_readable/descriptiles/ECOSYSTEM.a2ml` updated (if integrations changed) +- [ ] `.machine_readable/descriptiles/META.a2ml` updated (if architectural decisions changed) - [ ] Documentation updated for user-facing changes - [ ] `TOPOLOGY.md` updated (if architecture changed) - [ ] `CHANGELOG` or release notes updated diff --git a/.github/workflows/e2e.yml b/.github/workflow-templates/e2e.yml similarity index 97% rename from .github/workflows/e2e.yml rename to .github/workflow-templates/e2e.yml index fdb9ca1..40e1f5d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflow-templates/e2e.yml @@ -22,13 +22,15 @@ on: - 'tests/**' - '.github/workflows/e2e.yml' pull_request: - branches: [main, master] + branches: ['**'] paths: - 'src/**' - 'ffi/**' - 'tests/**' workflow_dispatch: -permissions: read-all +permissions: + contents: read + actions: read concurrency: group: e2e-${{ github.ref }} cancel-in-progress: true @@ -46,7 +48,7 @@ jobs: # - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable # - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 # - run: cargo build --release -# - run: bash tests/e2e.sh +# - run: bash tests/templates/e2e.sh.template # # OR: cargo test --test end_to_end -- --nocapture ## === ZIG FFI E2E === @@ -60,7 +62,7 @@ jobs: # with: # version: 0.15.0 # - run: cd ffi/zig && zig build test - # - run: bash tests/e2e.sh + # - run: bash tests/templates/e2e.sh.template ## === ELIXIR E2E === # e2e: diff --git a/.github/workflows/actions.lock b/.github/workflows/actions.lock new file mode 100644 index 0000000..df7f905 --- /dev/null +++ b/.github/workflows/actions.lock @@ -0,0 +1,93 @@ +# This file is machine-generated by `gh actions-lock`. +# Do not edit by hand; run `gh actions-lock` to update. +# Docs: https://gh.io/actions-lockfile +version: 'v0.0.2' +workflows: + '.github/workflows/boj-build.yml': + - 'actions/checkout@v7.0.1' + '.github/workflows/codeql.yml': + - 'actions/checkout@v7.0.1' + - 'github/codeql-action@v3.37.3' + '.github/workflows/dependabot-automerge.yml': + - 'dependabot/fetch-metadata@v3.1.0' + '.github/workflows/dogfood-gate.yml': + - 'actions/checkout@v7.0.1' + '.github/workflows/instant-sync.yml': + - 'peter-evans/repository-dispatch@v4.0.1' + '.github/workflows/openssf-compliance.yml': + - 'actions/checkout@v7.0.1' + '.github/workflows/pages.yml': + - 'actions/checkout@v7.0.1' + - 'actions/deploy-pages@v5.0.0' + - 'actions/upload-pages-artifact@v5.0.0' + '.github/workflows/release.yml': + - 'actions/checkout@v7.0.1' + - 'actions/upload-artifact@v7.0.1' + - 'softprops/action-gh-release@v3.0.2' + '.github/workflows/repository-validation.yml': + - 'actions/checkout@v7.0.1' + '.github/workflows/rhodibot.yml': + - 'actions/checkout@v7.0.1' + '.github/workflows/static-analysis-gate.yml': + - 'actions/checkout@v7.0.1' + - 'actions/download-artifact@v8.0.1' + - 'actions/upload-artifact@v7.0.1' + - 'erlef/setup-beam@v1.24.1' +dependencies: + 'actions/checkout@v7.0.1': + ref: 'v7.0.1' + commit: 'sha1-3d3c42e5aac5ba805825da76410c181273ba90b1' + owner_id: 44036562 + repo_id: 197814629 + 'actions/deploy-pages@v5.0.0': + ref: 'v5.0.0' + commit: 'sha1-cd2ce8fcbc39b97be8ca5fce6e763baed58fa128' + owner_id: 44036562 + repo_id: 438112499 + 'actions/download-artifact@v8.0.1': + ref: 'v8.0.1' + commit: 'sha1-3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c' + owner_id: 44036562 + repo_id: 192626254 + 'actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f': + ref: 'v7.0.0' + commit: 'sha1-bbbca2ddaa5d8feaa63e36b76fdaad77386f024f' + owner_id: 44036562 + repo_id: 192625955 + 'actions/upload-artifact@v7.0.1': + ref: 'v7.0.1' + commit: 'sha1-043fb46d1a93c77aae656e7c1c64a875d1fc6a0a' + owner_id: 44036562 + repo_id: 192625955 + 'actions/upload-pages-artifact@v5.0.0': + ref: 'v5.0.0' + commit: 'sha1-fc324d3547104276b827a68afc52ff2a11cc49c9' + owner_id: 44036562 + repo_id: 496012378 + uses: + - 'actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f' + 'dependabot/fetch-metadata@v3.1.0': + ref: 'v3.1.0' + commit: 'sha1-25dd0e34f4fe68f24cc83900b1fe3fe149efef98' + owner_id: 27347476 + repo_id: 371068214 + 'erlef/setup-beam@v1.24.1': + ref: 'v1.24.1' + commit: 'sha1-54075bcc5e249e4758d363f27d099f55d843f124' + owner_id: 47606891 + repo_id: 331103973 + 'github/codeql-action@v3.37.3': + ref: 'v3.37.3' + commit: 'sha1-4187e74d05793876e9989daffde9c3e66b4acd07' + owner_id: 9919 + repo_id: 259445878 + 'peter-evans/repository-dispatch@v4.0.1': + ref: 'v4.0.1' + commit: 'sha1-28959ce8df70de7be546dd1250a005dd32156697' + owner_id: 18365890 + repo_id: 220359305 + 'softprops/action-gh-release@v3.0.2': + ref: 'v3.0.2' + commit: 'sha1-3d0d9888cb7fd7b750713d6e236d1fcb99157228' + owner_id: 2242 + repo_id: 204253808 diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml index de12acb..63f4519 100644 --- a/.github/workflows/boj-build.yml +++ b/.github/workflows/boj-build.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 # // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 @@ -21,7 +22,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 - name: Trigger BoJ Server (Casket/ssg-mcp) env: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index d42c3dc..5e72424 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 # // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 @@ -6,7 +7,7 @@ on: push: branches: [main, master] pull_request: - branches: [main, master] + branches: ['**'] schedule: - cron: '0 6 1 * *' # monthly 1st 06:00 UTC @@ -35,14 +36,14 @@ jobs: build-mode: none steps: - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 - name: Initialize CodeQL - uses: github/codeql-action/init@4187e74d05793876e9989daffde9c3e66b4acd07 # v3 + uses: github/codeql-action/init@v3.37.3 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4187e74d05793876e9989daffde9c3e66b4acd07 # v3 + uses: github/codeql-action/analyze@v3.37.3 with: category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index a5fb89f..5def753 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 # // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 @@ -48,13 +49,13 @@ permissions: jobs: automerge: # Only run for PRs actually authored by Dependabot. - if: github.actor == 'dependabot[bot]' && github.event.pull_request.user.login == 'dependabot[bot]' + if: github.actor_id == '49699333' && github.event.pull_request.user.login == 'dependabot[bot]' runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Fetch Dependabot metadata id: meta - uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0 + uses: dependabot/fetch-metadata@v3.1.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} # --- Policy gate ------------------------------------------------------- diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index b699c60..bd2771b 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # @@ -11,7 +12,6 @@ on: push: branches: [main, master] permissions: - actions: read contents: read jobs: # --------------------------------------------------------------------------- @@ -23,7 +23,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 - name: Check for A2ML files id: detect @@ -61,7 +61,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 - name: Check for K9 files id: detect @@ -104,7 +104,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 - name: Scan for invisible characters id: lint @@ -166,7 +166,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 - name: Check for Groove manifest id: groove @@ -224,7 +224,7 @@ jobs: if: always() steps: - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 - name: Generate dogfooding scorecard run: | diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 931cef9..3c51090 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 name: Governance @@ -5,7 +6,7 @@ on: push: branches: [main, master] pull_request: - branches: [main, master] + branches: ['**'] workflow_dispatch: permissions: @@ -14,4 +15,4 @@ permissions: jobs: governance: - uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9 + uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@da2c748aad55c1a1dcba00b60fe4a35017bc6540 diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index 3c08e0a..b3c3bae 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 name: Hypatia Security Scan @@ -5,7 +6,7 @@ on: push: branches: [main, master, develop] pull_request: - branches: [main, master] + branches: ['**'] schedule: - cron: '0 0 * * 0' workflow_dispatch: @@ -17,4 +18,4 @@ permissions: jobs: scan: - uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9 + uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@da2c748aad55c1a1dcba00b60fe4a35017bc6540 diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index 577a104..6489936 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 # // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 @@ -15,9 +16,12 @@ jobs: dispatch: runs-on: ubuntu-latest timeout-minutes: 15 + env: + FARM_DISPATCH_TOKEN: ${{ secrets.FARM_DISPATCH_TOKEN }} steps: - name: Trigger Propagation - uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v3 + if: env.FARM_DISPATCH_TOKEN != '' + uses: peter-evans/repository-dispatch@v4.0.1 with: token: ${{ secrets.FARM_DISPATCH_TOKEN }} repository: hyperpolymath/.git-private-farm @@ -30,6 +34,10 @@ jobs: "forges": "" } - name: Confirm + if: env.FARM_DISPATCH_TOKEN != '' env: REPO_NAME: ${{ github.event.repository.name }} run: echo "::notice::Propagation triggered for ${REPO_NAME}" + - name: Propagation not configured + if: env.FARM_DISPATCH_TOKEN == '' + run: echo "::notice::FARM_DISPATCH_TOKEN is not configured; propagation was not requested" diff --git a/.github/workflows/label-triage.yml b/.github/workflows/label-triage.yml index 9886e92..814a192 100644 --- a/.github/workflows/label-triage.yml +++ b/.github/workflows/label-triage.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 name: Label Triage diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index c80b676..83ab941 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 name: Labels diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index c0c9631..9087230 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 # // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 @@ -11,5 +12,12 @@ permissions: contents: read jobs: mirror: - uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@5b1d00229e5e8c0c0fbfedc7e80f37ea50f49236 - secrets: inherit + uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@da2c748aad55c1a1dcba00b60fe4a35017bc6540 + secrets: + GITLAB_SSH_KEY: ${{ secrets.GITLAB_SSH_KEY }} + BITBUCKET_SSH_KEY: ${{ secrets.BITBUCKET_SSH_KEY }} + CODEBERG_SSH_KEY: ${{ secrets.CODEBERG_SSH_KEY }} + SOURCEHUT_SSH_KEY: ${{ secrets.SOURCEHUT_SSH_KEY }} + DISROOT_SSH_KEY: ${{ secrets.DISROOT_SSH_KEY }} + GITEA_SSH_KEY: ${{ secrets.GITEA_SSH_KEY }} + RADICLE_KEY: ${{ secrets.RADICLE_KEY }} diff --git a/.github/workflows/openssf-compliance.yml b/.github/workflows/openssf-compliance.yml index c711cc8..c47b905 100644 --- a/.github/workflows/openssf-compliance.yml +++ b/.github/workflows/openssf-compliance.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 # // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 @@ -8,7 +9,7 @@ on: push: branches: [main] pull_request: - branches: [main] + branches: ['**'] workflow_dispatch: permissions: actions: read @@ -20,7 +21,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/checkout@v7.0.1 with: persist-credentials: false - name: Check SECURITY.md exists and has substance @@ -69,11 +70,11 @@ jobs: exit 1 fi - if [ ! -f ".machine_readable/STATE.a2ml" ]; then - echo "::error::.machine_readable/STATE.a2ml is required" + if [ ! -f ".machine_readable/descriptiles/STATE.a2ml" ]; then + echo "::error::.machine_readable/descriptiles/STATE.a2ml is required" exit 1 fi - echo ".machine_readable/STATE.a2ml: OK" + echo ".machine_readable/descriptiles/STATE.a2ml: OK" - name: Check CHANGELOG exists run: | if [ ! -f "CHANGELOG.md" ] && [ ! -f "CHANGELOG.adoc" ] && [ ! -f "CHANGES.md" ]; then @@ -89,8 +90,8 @@ jobs: # Collect all required files that exist for f in SECURITY.md SECURITY.adoc .github/SECURITY.md LICENSE LICENSE.txt \ CONTRIBUTING.md CONTRIBUTING.adoc README.md README.adoc \ - .machine_readable/STATE.a2ml .machine_readable/META.a2ml \ - .machine_readable/ECOSYSTEM.a2ml CHANGELOG.md CHANGELOG.adoc; do + .machine_readable/descriptiles/STATE.a2ml .machine_readable/descriptiles/META.a2ml \ + .machine_readable/descriptiles/ECOSYSTEM.a2ml CHANGELOG.md CHANGELOG.adoc; do [ -f "$f" ] && REQUIRED_FILES="$REQUIRED_FILES $f" done diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 31f3ddc..c97b938 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 name: GitHub Pages (Ddraig SSG) on: @@ -20,9 +21,9 @@ jobs: image: ghcr.io/stefan-hoeck/idris2-pack@sha256:f0758996a931fb35d9ecb1de273c4d59dabe2a09b433afc7e357f65a08b7e1ff steps: - name: Checkout Site - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 - name: Checkout Ddraig SSG - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 with: repository: hyperpolymath/ddraig-ssg path: .ddraig-ssg @@ -39,7 +40,7 @@ jobs: fi ./.ddraig-ssg/build/exec/ddraig build src _site https://hyperpolymath.github.io/${GITHUB_REPOSITORY#*/} - name: Upload artifact - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 + uses: actions/upload-pages-artifact@v5.0.0 with: path: '_site' deploy: @@ -52,4 +53,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 + uses: actions/deploy-pages@v5.0.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 40a2f6d..938fee7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # @@ -20,7 +21,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/checkout@v7.0.1 - name: Detect project type and build id: build @@ -82,7 +83,7 @@ jobs: changelog: ${{ steps.cliff.outputs.content }} version: ${{ steps.version.outputs.version }} steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/checkout@v7.0.1 with: fetch-depth: 0 - name: Extract version from tag @@ -107,7 +108,7 @@ jobs: run: | git cliff --output CHANGELOG.md - name: Upload updated CHANGELOG.md - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@v7.0.1 with: name: changelog path: CHANGELOG.md @@ -120,7 +121,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: actions/checkout@v7.0.1 # TODO: Download build artifacts if uploading to the release # - uses: actions/download-artifact@v4 @@ -128,7 +129,7 @@ jobs: # name: release-artifacts # path: artifacts/ - name: Create GitHub Release - uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v2 + uses: softprops/action-gh-release@v3.0.2 with: body: ${{ needs.changelog.outputs.changelog }} draft: false diff --git a/.github/workflows/repository-validation.yml b/.github/workflows/repository-validation.yml new file mode 100644 index 0000000..02edc53 --- /dev/null +++ b/.github/workflows/repository-validation.yml @@ -0,0 +1,35 @@ +# This workflow is managed by gh actions-lock. +# SPDX-License-Identifier: MPL-2.0 +name: Repository Validation +on: + push: + branches: [main, master] + pull_request: + workflow_dispatch: +permissions: + contents: read +jobs: + repository-validation: + name: Workflow and session contract validation + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v7.0.1 + with: + persist-credentials: false + - name: Install verified Nickel 1.17.0 + run: | + mkdir -p "$RUNNER_TEMP/nickel-bin" + curl --proto '=https' --proto-redir '=https' --fail --silent --show-error --location \ + https://github.com/nickel-lang/nickel/releases/download/1.17.0/nickel-x86_64-linux \ + --output "$RUNNER_TEMP/nickel-bin/nickel" + echo "afcdfa6e0fff31760cf229e85997456c02c00b8b3b84ff38f897ac7b3f39ae34 $RUNNER_TEMP/nickel-bin/nickel" | sha256sum --check --strict + chmod +x "$RUNNER_TEMP/nickel-bin/nickel" + echo "$RUNNER_TEMP/nickel-bin" >> "$GITHUB_PATH" + - name: Check workflow conventions + run: bash tests/workflows/validate_workflows_test.sh + - name: Check Nickel envelope regression controls + run: bash tests/workflows/k9_typecheck_test.sh + - name: Evaluate session contracts + run: bash scripts/validate-session-contracts.sh + diff --git a/.github/workflows/rhodibot.yml b/.github/workflows/rhodibot.yml index c529564..860eab5 100644 --- a/.github/workflows/rhodibot.yml +++ b/.github/workflows/rhodibot.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 # // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 @@ -30,7 +31,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 with: fetch-depth: 1 - name: Rhodibot — Scan and Fix diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 11cf6c5..a750932 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -1,7 +1,10 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 name: OSSF Scorecard on: + pull_request: + branches: ["**"] schedule: - cron: '0 4 * * *' workflow_dispatch: @@ -13,7 +16,7 @@ permissions: id-token: write jobs: scorecard: - uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@5b1d00229e5e8c0c0fbfedc7e80f37ea50f49236 + uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@da2c748aad55c1a1dcba00b60fe4a35017bc6540 permissions: contents: read security-events: write diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 9149329..6e361d8 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 # // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 @@ -17,5 +18,4 @@ jobs: scan: permissions: contents: read - uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@c65436ee3351cd6b0fa14b142938b195efc77586 - secrets: inherit + uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@da2c748aad55c1a1dcba00b60fe4a35017bc6540 diff --git a/.github/workflows/static-analysis-gate.yml b/.github/workflows/static-analysis-gate.yml index 89ee2d0..5cf88d8 100644 --- a/.github/workflows/static-analysis-gate.yml +++ b/.github/workflows/static-analysis-gate.yml @@ -1,3 +1,4 @@ +# This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 # // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 @@ -22,7 +23,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 with: fetch-depth: 0 - name: Install panic-attack (if available) @@ -69,7 +70,7 @@ jobs: TOTAL=$(jq '. | length' panic-attack-findings.json 2>/dev/null || echo 0) CRITICAL=$(jq '[.[] | select(.severity == "critical")] | length' panic-attack-findings.json 2>/dev/null || echo 0) HIGH=$(jq '[.[] | select(.severity == "high")] | length' panic-attack-findings.json 2>/dev/null || echo 0) - MEDIUM=$(jq '[.[] | select(.severity == "medium")] | length' panic-attack-findings.json 2>/dev/null || echo 0) + MEDIUM=$(jq '[.[] | select(.severity == "medium" or .severity == "warn")] | length' panic-attack-findings.json 2>/dev/null || echo 0) LOW=$(jq '[.[] | select(.severity == "low")] | length' panic-attack-findings.json 2>/dev/null || echo 0) echo "total=$TOTAL" >> "$GITHUB_OUTPUT" @@ -119,7 +120,7 @@ jobs: echo "" >> "$GITHUB_STEP_SUMMARY" echo "Skipped: panic-attack not available in this environment." >> "$GITHUB_STEP_SUMMARY" - name: Upload panic-attack findings - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@v7.0.1 with: name: panic-attack-findings path: panic-attack-findings.json @@ -138,13 +139,13 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 with: fetch-depth: 0 - name: Setup Elixir for Hypatia scanner id: beam continue-on-error: true - uses: erlef/setup-beam@54075bcc5e249e4758d363f27d099f55d843f124 # v1.18.2 + uses: erlef/setup-beam@v1.24.1 with: elixir-version: '1.19.4' otp-version: '28.3' @@ -197,7 +198,7 @@ jobs: TOTAL=$(jq '. | length' hypatia-findings.json 2>/dev/null || echo 0) CRITICAL=$(jq '[.[] | select(.severity == "critical")] | length' hypatia-findings.json 2>/dev/null || echo 0) HIGH=$(jq '[.[] | select(.severity == "high")] | length' hypatia-findings.json 2>/dev/null || echo 0) - MEDIUM=$(jq '[.[] | select(.severity == "medium")] | length' hypatia-findings.json 2>/dev/null || echo 0) + MEDIUM=$(jq '[.[] | select(.severity == "medium" or .severity == "warn")] | length' hypatia-findings.json 2>/dev/null || echo 0) LOW=$(jq '[.[] | select(.severity == "low")] | length' hypatia-findings.json 2>/dev/null || echo 0) echo "total=$TOTAL" >> "$GITHUB_OUTPUT" @@ -245,7 +246,7 @@ jobs: echo "" >> "$GITHUB_STEP_SUMMARY" echo "Skipped: Hypatia scanner not available in this environment." >> "$GITHUB_STEP_SUMMARY" - name: Upload hypatia findings - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@v7.0.1 with: name: hypatia-findings path: hypatia-findings.json @@ -264,7 +265,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + uses: actions/checkout@v7.0.1 with: fetch-depth: 0 - name: Install panic-attack (if available) @@ -326,7 +327,7 @@ jobs: echo "" >> "$GITHUB_STEP_SUMMARY" echo "Skipped: panic-attack not available in this environment." >> "$GITHUB_STEP_SUMMARY" - name: Upload bridge report - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@v7.0.1 with: name: bridge-report path: bridge-report.json @@ -348,17 +349,17 @@ jobs: if: always() steps: - name: Download panic-attack findings - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v4 + uses: actions/download-artifact@v8.0.1 with: name: panic-attack-findings path: findings/ - name: Download hypatia findings - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v4 + uses: actions/download-artifact@v8.0.1 with: name: hypatia-findings path: findings/ - name: Download bridge report - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v4 + uses: actions/download-artifact@v8.0.1 with: name: bridge-report path: findings/ @@ -409,7 +410,7 @@ jobs: TOTAL=$(jq '.findings | length' findings/unified-findings.json) CRITICAL=$(jq '[.findings[] | select(.severity == "critical")] | length' findings/unified-findings.json) HIGH=$(jq '[.findings[] | select(.severity == "high")] | length' findings/unified-findings.json) - MEDIUM=$(jq '[.findings[] | select(.severity == "medium")] | length' findings/unified-findings.json) + MEDIUM=$(jq '[.findings[] | select(.severity == "medium" or .severity == "warn")] | length' findings/unified-findings.json) LOW=$(jq '[.findings[] | select(.severity == "low")] | length' findings/unified-findings.json) echo "total=$TOTAL" >> "$GITHUB_OUTPUT" @@ -418,7 +419,7 @@ jobs: echo "medium=$MEDIUM" >> "$GITHUB_OUTPUT" echo "low=$LOW" >> "$GITHUB_OUTPUT" - name: Upload unified findings (fleet scanner picks these up) - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@v7.0.1 with: name: unified-findings path: findings/unified-findings.json diff --git a/.machine_readable/ECOSYSTEM.a2ml b/.machine_readable/ECOSYSTEM.a2ml deleted file mode 100644 index 0059aed..0000000 --- a/.machine_readable/ECOSYSTEM.a2ml +++ /dev/null @@ -1,8 +0,0 @@ -;; SPDX-License-Identifier: MPL-2.0 -;; Ecosystem position and relationships -(ecosystem - (version "1.0.0") - (name "{{REPO}}") - (type "library") - (purpose "{{REPO_DESCRIPTION}}") - (related-projects)) diff --git a/.machine_readable/META.a2ml b/.machine_readable/META.a2ml deleted file mode 100644 index e64e280..0000000 --- a/.machine_readable/META.a2ml +++ /dev/null @@ -1,10 +0,0 @@ -;; SPDX-License-Identifier: MPL-2.0 -;; Architecture decisions and development practices -(meta - (version "1.0.0") - (project "{{REPO}}") - (architecture-decisions) - (development-practices - (code-review "required") - (branch-protection "enabled") - (ci-cd "github-actions"))) diff --git a/.machine_readable/ai/.clinerules b/.machine_readable/ai/.clinerules index a29ed5f..30d21a5 100644 --- a/.machine_readable/ai/.clinerules +++ b/.machine_readable/ai/.clinerules @@ -2,7 +2,7 @@ # Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> # Authoritative source: docs/AI-CONVENTIONS.md -# STARTUP: Read 0-AI-MANIFEST.a2ml first, then .machine_readable/STATE.a2ml. +# STARTUP: Read 0-AI-MANIFEST.a2ml first, then .machine_readable/descriptiles/STATE.a2ml. # LICENSE # All original code: MPL-2.0. diff --git a/.machine_readable/ai/.windsurfrules b/.machine_readable/ai/.windsurfrules index a29ed5f..30d21a5 100644 --- a/.machine_readable/ai/.windsurfrules +++ b/.machine_readable/ai/.windsurfrules @@ -2,7 +2,7 @@ # Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> # Authoritative source: docs/AI-CONVENTIONS.md -# STARTUP: Read 0-AI-MANIFEST.a2ml first, then .machine_readable/STATE.a2ml. +# STARTUP: Read 0-AI-MANIFEST.a2ml first, then .machine_readable/descriptiles/STATE.a2ml. # LICENSE # All original code: MPL-2.0. diff --git a/.machine_readable/ai/AI.a2ml b/.machine_readable/ai/AI.a2ml index 1f8b521..f0c73a8 100644 --- a/.machine_readable/ai/AI.a2ml +++ b/.machine_readable/ai/AI.a2ml @@ -7,8 +7,8 @@ - Prefer to keep generated files out of source control, and regenerate them with the documented commands before committing. ## Workflow -1. Inspect `.machine_readable/STATE.a2ml` for blockers and next actions. -2. Respect any constraints listed inside `.machine_readable/AGENTIC.a2ml` when tooling changes are requested. +1. Inspect `.machine_readable/descriptiles/STATE.a2ml` for blockers and next actions. +2. Respect any constraints listed inside `.machine_readable/descriptiles/AGENTIC.a2ml` when tooling changes are requested. 3. After finishing edits, update STATE with your outcomes and commit with a concise, imperative message. ## Delivery Promises diff --git a/.machine_readable/ai/README.adoc b/.machine_readable/ai/README.adoc index 7d90fea..a41aed1 100644 --- a/.machine_readable/ai/README.adoc +++ b/.machine_readable/ai/README.adoc @@ -20,5 +20,5 @@ Recommended machine read order: * `.machine_readable/policies/MAINTENANCE-AXES.a2ml` * `.machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml` * `.machine_readable/policies/SOFTWARE-DEVELOPMENT-APPROACH.a2ml` -* `.machine_readable/STATE.a2ml` -* `.machine_readable/META.a2ml` +* `.machine_readable/descriptiles/STATE.a2ml` +* `.machine_readable/descriptiles/META.a2ml` diff --git a/.machine_readable/contractiles/Justfile b/.machine_readable/contractiles/Justfile index 0457f2f..9392b5e 100644 --- a/.machine_readable/contractiles/Justfile +++ b/.machine_readable/contractiles/Justfile @@ -52,7 +52,7 @@ info: @echo "Version: {{version}}" @echo "RSR Tier: {{tier}}" @echo "Recipes: $(just --summary | wc -w)" - @[ -f ".machine_readable/STATE.a2ml" ] && grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/STATE.a2ml | head -1 | xargs -I{} echo "Phase: {}" || true + @[ -f ".machine_readable/descriptiles/STATE.a2ml" ] && grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/descriptiles/STATE.a2ml | head -1 | xargs -I{} echo "Phase: {}" || true # Run Invariant Path overlay tools for this repository invariant-path *ARGS: @@ -345,7 +345,7 @@ verify-template: fi # Check for empty SCM files - for f in .machine_readable/6a2/STATE.a2ml .machine_readable/6a2/META.a2ml .machine_readable/6a2/ECOSYSTEM.a2ml; do + for f in .machine_readable/descriptiles/STATE.a2ml .machine_readable/descriptiles/META.a2ml .machine_readable/descriptiles/ECOSYSTEM.a2ml; do if [ -f "$f" ] && grep -q '{{'{{'}}' "$f" 2>/dev/null; then echo "⚠ $f still has template placeholders" FOUND=1 @@ -403,10 +403,10 @@ self-assess: fi done - if [ -d ".machine_readable/6a2" ]; then - echo " ✓ .machine_readable/6a2/ — KEEP (SCM checkpoint files)" + if [ -d ".machine_readable/descriptiles" ]; then + echo " ✓ .machine_readable/descriptiles/ — KEEP (SCM checkpoint files)" else - echo " ✗ .machine_readable/6a2/ — MISSING (RSR violation!)" + echo " ✗ .machine_readable/descriptiles/ — MISSING (RSR violation!)" fi if [ -d ".github/workflows" ]; then @@ -559,9 +559,9 @@ verify: check_file "LICENSE" check_either "CONTRIBUTING.md" "CONTRIBUTING.adoc" check_either "README.adoc" "README.md" - check_file ".machine_readable/STATE.a2ml" - check_file ".machine_readable/META.a2ml" - check_file ".machine_readable/ECOSYSTEM.a2ml" + check_file ".machine_readable/descriptiles/STATE.a2ml" + check_file ".machine_readable/descriptiles/META.a2ml" + check_file ".machine_readable/descriptiles/ECOSYSTEM.a2ml" check_either "CHANGELOG.md" "CHANGELOG.adoc" # Check at least 1 workflow exists @@ -1051,7 +1051,7 @@ validate-rsr: for f in .editorconfig .gitignore Justfile README.adoc LICENSE 0-AI-MANIFEST.a2ml; do [ -f "$f" ] || MISSING="$MISSING $f" done - for f in .machine_readable/STATE.a2ml .machine_readable/META.a2ml .machine_readable/ECOSYSTEM.a2ml .machine_readable/anchors/ANCHOR.a2ml .machine_readable/policies/MAINTENANCE-AXES.a2ml .machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml .machine_readable/policies/SOFTWARE-DEVELOPMENT-APPROACH.a2ml; do + for f in .machine_readable/descriptiles/STATE.a2ml .machine_readable/descriptiles/META.a2ml .machine_readable/descriptiles/ECOSYSTEM.a2ml .machine_readable/anchors/ANCHOR.a2ml .machine_readable/policies/MAINTENANCE-AXES.a2ml .machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml .machine_readable/policies/SOFTWARE-DEVELOPMENT-APPROACH.a2ml; do [ -f "$f" ] || MISSING="$MISSING $f" done for f in licensing/exhibits/EXHIBIT-A-ETHICAL-USE.txt licensing/exhibits/EXHIBIT-B-QUANTUM-SAFE.txt licensing/texts/MPL-2.0.txt; do @@ -1066,15 +1066,15 @@ validate-rsr: for f in docs/governance/MAINTENANCE-CHECKLIST.adoc docs/governance/SOFTWARE-DEVELOPMENT-APPROACH.adoc; do [ -f "$f" ] || MISSING="$MISSING $f" done - if [ -f ".machine_readable/META.a2ml" ]; then - grep -q 'axis-1 = "must > intend > like"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:axis-1" - grep -q 'axis-2 = "corrective > adaptive > perfective"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:axis-2" - grep -q 'axis-3 = "systems > compliance > effects"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:axis-3" - grep -q 'scoping-first = true' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:scoping-first" - grep -q 'idris-unsound-scan = "believe_me/assert_total"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:idris-unsound-scan" - grep -q 'audit-focus = "systems in place, documentation explains actual state, safety/security accounted for, observed effects reviewed"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:audit-focus" - grep -q 'compliance-focus = "seams/compromises/exception register, bounded exceptions, anti-drift checks"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:compliance-focus" - grep -q 'effects-evidence = "benchmark execution/results and maintainer status dialogue/review"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:effects-evidence" + if [ -f ".machine_readable/descriptiles/META.a2ml" ]; then + grep -q 'axis-1 = "must > intend > like"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:axis-1" + grep -q 'axis-2 = "corrective > adaptive > perfective"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:axis-2" + grep -q 'axis-3 = "systems > compliance > effects"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:axis-3" + grep -q 'scoping-first = true' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:scoping-first" + grep -q 'idris-unsound-scan = "believe_me/assert_total"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:idris-unsound-scan" + grep -q 'audit-focus = "systems in place, documentation explains actual state, safety/security accounted for, observed effects reviewed"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:audit-focus" + grep -q 'compliance-focus = "seams/compromises/exception register, bounded exceptions, anti-drift checks"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:compliance-focus" + grep -q 'effects-evidence = "benchmark execution/results and maintainer status dialogue/review"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:effects-evidence" grep -q 'compliance-tooling = "panic-attack"' .machine_readable/policies/MAINTENANCE-AXES.a2ml || MISSING="$MISSING MAINTENANCE-AXES.a2ml:compliance-tooling" grep -q 'effects-tooling = "ecological checking with sustainabot guidance"' .machine_readable/policies/MAINTENANCE-AXES.a2ml || MISSING="$MISSING MAINTENANCE-AXES.a2ml:effects-tooling" grep -q 'source-human = "docs/governance/MAINTENANCE-CHECKLIST.adoc"' .machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml || MISSING="$MISSING MAINTENANCE-CHECKLIST.a2ml:source-human" @@ -1088,12 +1088,12 @@ validate-rsr: # Validate STATE.a2ml syntax validate-state: - @if [ -f ".machine_readable/STATE.a2ml" ]; then \ - grep -q '^\[metadata\]' .machine_readable/STATE.a2ml && \ - grep -q 'project\s*=' .machine_readable/STATE.a2ml && \ + @if [ -f ".machine_readable/descriptiles/STATE.a2ml" ]; then \ + grep -q '^\[metadata\]' .machine_readable/descriptiles/STATE.a2ml && \ + grep -q 'project\s*=' .machine_readable/descriptiles/STATE.a2ml && \ echo "STATE.a2ml: valid" || echo "STATE.a2ml: INVALID (missing required sections)"; \ else \ - echo "No .machine_readable/STATE.a2ml found"; \ + echo "No .machine_readable/descriptiles/STATE.a2ml found"; \ fi # Validate AI installation guide completeness (finishbot pre-release check) @@ -1170,14 +1170,14 @@ validate: validate-rsr validate-state validate-ai-install # Update STATE.a2ml timestamp state-touch: - @if [ -f ".machine_readable/STATE.a2ml" ]; then \ - sed -i 's/last-updated = "[^"]*"/last-updated = "'"$(date +%Y-%m-%d)"'"/' .machine_readable/STATE.a2ml && \ + @if [ -f ".machine_readable/descriptiles/STATE.a2ml" ]; then \ + sed -i 's/last-updated = "[^"]*"/last-updated = "'"$(date +%Y-%m-%d)"'"/' .machine_readable/descriptiles/STATE.a2ml && \ echo "STATE.a2ml timestamp updated"; \ fi # Show current phase from STATE.a2ml state-phase: - @grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/STATE.a2ml 2>/dev/null | head -1 || echo "unknown" + @grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/descriptiles/STATE.a2ml 2>/dev/null | head -1 || echo "unknown" # ═══════════════════════════════════════════════════════════════════════════════ # GUIX & NIX diff --git a/.machine_readable/contractiles/Mustfile.a2ml b/.machine_readable/contractiles/Mustfile.a2ml index 55f8ab4..9c9f869 100644 --- a/.machine_readable/contractiles/Mustfile.a2ml +++ b/.machine_readable/contractiles/Mustfile.a2ml @@ -63,12 +63,12 @@ hooks fail if any check fails. ### six-directory-present - description: 6a2 directory exists with required files -- run: test -d .machine_readable/6a2 && test -f .machine_readable/6a2/META.a2ml && test -f .machine_readable/6a2/ECOSYSTEM.a2ml && test -f .machine_readable/6a2/STATE.a2ml && test -f .machine_readable/6a2/PLAYBOOK.a2ml && test -f .machine_readable/6a2/AGENTIC.a2ml && test -f .machine_readable/6a2/NEUROSYM.a2ml +- run: test -d .machine_readable/descriptiles && test -f .machine_readable/descriptiles/META.a2ml && test -f .machine_readable/descriptiles/ECOSYSTEM.a2ml && test -f .machine_readable/descriptiles/STATE.a2ml && test -f .machine_readable/descriptiles/PLAYBOOK.a2ml && test -f .machine_readable/descriptiles/AGENTIC.a2ml && test -f .machine_readable/descriptiles/NEUROSYM.a2ml - severity: critical ### anchors-directory - description: anchors directory exists in 6a2 -- run: test -d .machine_readable/6a2/anchors +- run: test -d .machine_readable/descriptiles/anchors - severity: warning ### self-validating-structure diff --git a/.machine_readable/6a2/0-AI-MANIFEST.a2ml b/.machine_readable/descriptiles/0-AI-MANIFEST.a2ml similarity index 100% rename from .machine_readable/6a2/0-AI-MANIFEST.a2ml rename to .machine_readable/descriptiles/0-AI-MANIFEST.a2ml diff --git a/.machine_readable/6a2/AGENTIC.a2ml b/.machine_readable/descriptiles/AGENTIC.a2ml similarity index 100% rename from .machine_readable/6a2/AGENTIC.a2ml rename to .machine_readable/descriptiles/AGENTIC.a2ml diff --git a/.machine_readable/6a2/ECOSYSTEM.a2ml b/.machine_readable/descriptiles/ECOSYSTEM.a2ml similarity index 100% rename from .machine_readable/6a2/ECOSYSTEM.a2ml rename to .machine_readable/descriptiles/ECOSYSTEM.a2ml diff --git a/.machine_readable/6a2/META.a2ml b/.machine_readable/descriptiles/META.a2ml similarity index 97% rename from .machine_readable/6a2/META.a2ml rename to .machine_readable/descriptiles/META.a2ml index d9b09e6..d3b878f 100644 --- a/.machine_readable/6a2/META.a2ml +++ b/.machine_readable/descriptiles/META.a2ml @@ -19,6 +19,8 @@ author = "Jonathan D.A. Jewell (hyperpolymath)" # - { id = "ADR-001", title = "Use Zig for FFI", status = "accepted", date = "2026-02-14" } [development-practices] +code-review = "required" +branch-protection = "enabled" build-tool = "just" container-runtime = "podman" ci-platform = "github-actions" diff --git a/.machine_readable/6a2/NEUROSYM.a2ml b/.machine_readable/descriptiles/NEUROSYM.a2ml similarity index 100% rename from .machine_readable/6a2/NEUROSYM.a2ml rename to .machine_readable/descriptiles/NEUROSYM.a2ml diff --git a/.machine_readable/6a2/PLAYBOOK.a2ml b/.machine_readable/descriptiles/PLAYBOOK.a2ml similarity index 93% rename from .machine_readable/6a2/PLAYBOOK.a2ml rename to .machine_readable/descriptiles/PLAYBOOK.a2ml index 6408e1c..c7bd686 100644 --- a/.machine_readable/6a2/PLAYBOOK.a2ml +++ b/.machine_readable/descriptiles/PLAYBOOK.a2ml @@ -13,7 +13,7 @@ last-updated = "2026-04-11" # target = "container" # container | binary | library | wasm [incident-response] -# 1. Check .machine_readable/STATE.a2ml for current status +# 1. Check .machine_readable/descriptiles/STATE.a2ml for current status # 2. Review recent commits and CI results # 3. Run `just validate` to check compliance # 4. Run `just security` to audit for vulnerabilities diff --git a/.machine_readable/6a2/README.adoc b/.machine_readable/descriptiles/README.adoc similarity index 100% rename from .machine_readable/6a2/README.adoc rename to .machine_readable/descriptiles/README.adoc diff --git a/.machine_readable/6a2/STATE.a2ml b/.machine_readable/descriptiles/STATE.a2ml similarity index 100% rename from .machine_readable/6a2/STATE.a2ml rename to .machine_readable/descriptiles/STATE.a2ml diff --git a/.machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml b/.machine_readable/descriptiles/anchor/0-AI-MANIFEST.a2ml similarity index 100% rename from .machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml rename to .machine_readable/descriptiles/anchor/0-AI-MANIFEST.a2ml diff --git a/.machine_readable/6a2/anchor/ANCHOR.a2ml b/.machine_readable/descriptiles/anchor/ANCHOR.a2ml similarity index 100% rename from .machine_readable/6a2/anchor/ANCHOR.a2ml rename to .machine_readable/descriptiles/anchor/ANCHOR.a2ml diff --git a/.machine_readable/6a2/anchor/README.adoc b/.machine_readable/descriptiles/anchor/README.adoc similarity index 100% rename from .machine_readable/6a2/anchor/README.adoc rename to .machine_readable/descriptiles/anchor/README.adoc diff --git a/.machine_readable/policies/MAINTENANCE-AXES.a2ml b/.machine_readable/policies/MAINTENANCE-AXES.a2ml index eeffd27..c073b9a 100644 --- a/.machine_readable/policies/MAINTENANCE-AXES.a2ml +++ b/.machine_readable/policies/MAINTENANCE-AXES.a2ml @@ -18,7 +18,7 @@ machine-entrypoints = [ ".machine_readable/policies/MAINTENANCE-AXES.a2ml", ".machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml", ".machine_readable/policies/SOFTWARE-DEVELOPMENT-APPROACH.a2ml", - ".machine_readable/META.a2ml", + ".machine_readable/descriptiles/META.a2ml", ".machine_readable/ai/README.adoc", ".machine_readable/bot_directives/README.scm", ] diff --git a/0-AI-MANIFEST.a2ml b/0-AI-MANIFEST.a2ml index 86db391..907a430 100644 --- a/0-AI-MANIFEST.a2ml +++ b/0-AI-MANIFEST.a2ml @@ -27,7 +27,7 @@ co-developed-with = "son" [canonical-locations] contractiles = ".machine_readable/contractiles/" -state-descriptive = ".machine_readable/6a2/" +state-descriptive = ".machine_readable/descriptiles/" recalibration-records = ".machine_readable/anchors/" source-libraries = "libs/" tools = "tools/" diff --git a/EXPLAINME.adoc b/EXPLAINME.adoc index d8b6d97..dad7cb7 100644 --- a/EXPLAINME.adoc +++ b/EXPLAINME.adoc @@ -15,8 +15,8 @@ How this is implemented: * The local dispatcher (`session/dispatch.sh`) maps canonical commands to central protocol paths in `standards/session-management-standards`. -* Local files (`session/custom-checks.k9`, `session/local-hooks.sh`, - `coordination.k9`) are integration-only. +* Local files (`session/custom-checks.k9.ncl`, `session/local-hooks.sh`, + `coordination.k9.ncl`) are integration-only. Caveat: diff --git a/Justfile b/Justfile index 5632b4a..8536a00 100644 --- a/Justfile +++ b/Justfile @@ -53,7 +53,7 @@ info: @echo "Version: {{version}}" @echo "RSR Tier: {{tier}}" @echo "Recipes: $(just --summary | wc -w)" - @[ -f ".machine_readable/STATE.a2ml" ] && grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/STATE.a2ml | head -1 | xargs -I{} echo "Phase: {}" || true + @[ -f ".machine_readable/descriptiles/STATE.a2ml" ] && grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/descriptiles/STATE.a2ml | head -1 | xargs -I{} echo "Phase: {}" || true # Run Invariant Path overlay tools for this repository invariant-path *ARGS: @@ -250,11 +250,11 @@ init: echo "All placeholders replaced successfully!" fi - # K9-SVC validation (if available) - if command -v k9-svc >/dev/null 2>&1; then - echo "" - echo "Running k9-svc validation..." - k9-svc validate . 2>/dev/null || true + # CI always provisions Nickel; local initialisation can precede that environment. + if command -v nickel >/dev/null; then + bash scripts/validate-session-contracts.sh + else + echo "Session validation deferred: install Nickel 1.17.0, then run bash scripts/validate-session-contracts.sh" fi echo "" @@ -346,7 +346,7 @@ verify-template: fi # Check for empty SCM files - for f in .machine_readable/6a2/STATE.a2ml .machine_readable/6a2/META.a2ml .machine_readable/6a2/ECOSYSTEM.a2ml; do + for f in .machine_readable/descriptiles/STATE.a2ml .machine_readable/descriptiles/META.a2ml .machine_readable/descriptiles/ECOSYSTEM.a2ml; do if [ -f "$f" ] && grep -q '{{'{{'}}' "$f" 2>/dev/null; then echo "⚠ $f still has template placeholders" FOUND=1 @@ -404,10 +404,10 @@ self-assess: fi done - if [ -d ".machine_readable/6a2" ]; then - echo " ✓ .machine_readable/6a2/ — KEEP (SCM checkpoint files)" + if [ -d ".machine_readable/descriptiles" ]; then + echo " ✓ .machine_readable/descriptiles/ — KEEP (SCM checkpoint files)" else - echo " ✗ .machine_readable/6a2/ — MISSING (RSR violation!)" + echo " ✗ .machine_readable/descriptiles/ — MISSING (RSR violation!)" fi if [ -d ".github/workflows" ]; then @@ -560,9 +560,9 @@ verify: check_file "LICENSE" check_either "CONTRIBUTING.md" "CONTRIBUTING.adoc" check_either "README.adoc" "README.md" - check_file ".machine_readable/STATE.a2ml" - check_file ".machine_readable/META.a2ml" - check_file ".machine_readable/ECOSYSTEM.a2ml" + check_file ".machine_readable/descriptiles/STATE.a2ml" + check_file ".machine_readable/descriptiles/META.a2ml" + check_file ".machine_readable/descriptiles/ECOSYSTEM.a2ml" check_either "CHANGELOG.md" "CHANGELOG.adoc" # Check at least 1 workflow exists @@ -652,13 +652,8 @@ test-smoke: # Run end-to-end tests (full pipeline: build → run → verify) e2e: - @echo "Running E2E tests..." - # TODO: Replace with your E2E test command. Examples: - # bash tests/e2e.sh # Shell-based E2E - # npx playwright test # Browser E2E - # mix test test/integration/e2e_test.exs # Elixir E2E - # cargo test --test end_to_end # Rust E2E - @echo "E2E tests passed!" + @echo "E2E tests are not implemented. Start from tests/templates/e2e.sh.template." >&2 + @exit 2 # Run aspect tests (cross-cutting concern validation) aspect: @@ -1052,7 +1047,7 @@ validate-rsr: for f in .editorconfig .gitignore Justfile README.adoc LICENSE 0-AI-MANIFEST.a2ml; do [ -f "$f" ] || MISSING="$MISSING $f" done - for f in .machine_readable/STATE.a2ml .machine_readable/META.a2ml .machine_readable/ECOSYSTEM.a2ml .machine_readable/anchors/ANCHOR.a2ml .machine_readable/policies/MAINTENANCE-AXES.a2ml .machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml .machine_readable/policies/SOFTWARE-DEVELOPMENT-APPROACH.a2ml; do + for f in .machine_readable/descriptiles/STATE.a2ml .machine_readable/descriptiles/META.a2ml .machine_readable/descriptiles/ECOSYSTEM.a2ml .machine_readable/descriptiles/anchor/ANCHOR.a2ml .machine_readable/policies/MAINTENANCE-AXES.a2ml .machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml .machine_readable/policies/SOFTWARE-DEVELOPMENT-APPROACH.a2ml; do [ -f "$f" ] || MISSING="$MISSING $f" done for f in licensing/exhibits/EXHIBIT-A-ETHICAL-USE.txt licensing/exhibits/EXHIBIT-B-QUANTUM-SAFE.txt licensing/texts/MPL-2.0.txt; do @@ -1067,15 +1062,15 @@ validate-rsr: for f in docs/governance/MAINTENANCE-CHECKLIST.adoc docs/governance/SOFTWARE-DEVELOPMENT-APPROACH.adoc; do [ -f "$f" ] || MISSING="$MISSING $f" done - if [ -f ".machine_readable/META.a2ml" ]; then - grep -q 'axis-1 = "must > intend > like"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:axis-1" - grep -q 'axis-2 = "corrective > adaptive > perfective"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:axis-2" - grep -q 'axis-3 = "systems > compliance > effects"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:axis-3" - grep -q 'scoping-first = true' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:scoping-first" - grep -q 'idris-unsound-scan = "believe_me/assert_total"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:idris-unsound-scan" - grep -q 'audit-focus = "systems in place, documentation explains actual state, safety/security accounted for, observed effects reviewed"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:audit-focus" - grep -q 'compliance-focus = "seams/compromises/exception register, bounded exceptions, anti-drift checks"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:compliance-focus" - grep -q 'effects-evidence = "benchmark execution/results and maintainer status dialogue/review"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:effects-evidence" + if [ -f ".machine_readable/descriptiles/META.a2ml" ]; then + grep -q 'axis-1 = "must > intend > like"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:axis-1" + grep -q 'axis-2 = "corrective > adaptive > perfective"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:axis-2" + grep -q 'axis-3 = "systems > compliance > effects"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:axis-3" + grep -q 'scoping-first = true' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:scoping-first" + grep -q 'idris-unsound-scan = "believe_me/assert_total"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:idris-unsound-scan" + grep -q 'audit-focus = "systems in place, documentation explains actual state, safety/security accounted for, observed effects reviewed"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:audit-focus" + grep -q 'compliance-focus = "seams/compromises/exception register, bounded exceptions, anti-drift checks"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:compliance-focus" + grep -q 'effects-evidence = "benchmark execution/results and maintainer status dialogue/review"' .machine_readable/descriptiles/META.a2ml || MISSING="$MISSING META.a2ml:effects-evidence" grep -q 'compliance-tooling = "panic-attack"' .machine_readable/policies/MAINTENANCE-AXES.a2ml || MISSING="$MISSING MAINTENANCE-AXES.a2ml:compliance-tooling" grep -q 'effects-tooling = "ecological checking with sustainabot guidance"' .machine_readable/policies/MAINTENANCE-AXES.a2ml || MISSING="$MISSING MAINTENANCE-AXES.a2ml:effects-tooling" grep -q 'source-human = "docs/governance/MAINTENANCE-CHECKLIST.adoc"' .machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml || MISSING="$MISSING MAINTENANCE-CHECKLIST.a2ml:source-human" @@ -1089,12 +1084,12 @@ validate-rsr: # Validate STATE.a2ml syntax validate-state: - @if [ -f ".machine_readable/STATE.a2ml" ]; then \ - grep -q '^\[metadata\]' .machine_readable/STATE.a2ml && \ - grep -q 'project\s*=' .machine_readable/STATE.a2ml && \ + @if [ -f ".machine_readable/descriptiles/STATE.a2ml" ]; then \ + grep -q '^\[metadata\]' .machine_readable/descriptiles/STATE.a2ml && \ + grep -q 'project\s*=' .machine_readable/descriptiles/STATE.a2ml && \ echo "STATE.a2ml: valid" || echo "STATE.a2ml: INVALID (missing required sections)"; \ else \ - echo "No .machine_readable/STATE.a2ml found"; \ + echo "No .machine_readable/descriptiles/STATE.a2ml found"; \ fi # Validate AI installation guide completeness (finishbot pre-release check) @@ -1171,14 +1166,14 @@ validate: validate-rsr validate-state validate-ai-install # Update STATE.a2ml timestamp state-touch: - @if [ -f ".machine_readable/STATE.a2ml" ]; then \ - sed -i 's/last-updated = "[^"]*"/last-updated = "'"$(date +%Y-%m-%d)"'"/' .machine_readable/STATE.a2ml && \ + @if [ -f ".machine_readable/descriptiles/STATE.a2ml" ]; then \ + sed -i 's/last-updated = "[^"]*"/last-updated = "'"$(date +%Y-%m-%d)"'"/' .machine_readable/descriptiles/STATE.a2ml && \ echo "STATE.a2ml timestamp updated"; \ fi # Show current phase from STATE.a2ml state-phase: - @grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/STATE.a2ml 2>/dev/null | head -1 || echo "unknown" + @grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/descriptiles/STATE.a2ml 2>/dev/null | head -1 || echo "unknown" # ═══════════════════════════════════════════════════════════════════════════════ # GUIX & NIX diff --git a/container/README.adoc b/container/README.adoc index 78275d2..a147763 100644 --- a/container/README.adoc +++ b/container/README.adoc @@ -154,8 +154,8 @@ For k9-svc managed deployments: [source,bash] ---- -# Validate the deployment component -nickel typecheck container/deploy.k9.ncl +# After just init has replaced template values, typecheck without deploying +bash scripts/validate-session-contracts.sh --typecheck container/deploy.k9.ncl # Deploy (requires Hunt-level authorisation) k9-svc deploy container/deploy.k9.ncl --env production diff --git a/coordination.k9 b/coordination.k9.ncl similarity index 87% rename from coordination.k9 rename to coordination.k9.ncl index 3c5160c..44ce7c6 100644 --- a/coordination.k9 +++ b/coordination.k9.ncl @@ -5,18 +5,12 @@ K9! { pedigree = { schema_version = "1.0.0", - component_type = "session-coordination", - security = { - leash = 'Kennel, - trust_level = "data-only", - allow_network = false, - allow_filesystem_write = false, - allow_subprocess = false, - }, metadata = { name = "session-coordination", version = "0.1.0", - description = "Bindings for the central session-management standards", + }, + security = { + leash = 'Kennel, }, }, diff --git a/docs/RSR_OUTLINE.adoc b/docs/RSR_OUTLINE.adoc index f6e9a9a..03fdcde 100644 --- a/docs/RSR_OUTLINE.adoc +++ b/docs/RSR_OUTLINE.adoc @@ -161,12 +161,13 @@ project/ │ ├── humans.txt │ └── security.txt ├── .machine_readable/ # ALL machine-readable content -│ ├── STATE.a2ml # Project state, progress, blockers -│ ├── META.a2ml # Architecture decisions, governance -│ ├── ECOSYSTEM.a2ml # Ecosystem position, relationships -│ ├── AGENTIC.a2ml # AI agent interaction patterns -│ ├── NEUROSYM.a2ml # Neurosymbolic integration config -│ ├── PLAYBOOK.a2ml # Operational runbook +│ ├── descriptiles/ # Canonical descriptive anchors +│ │ ├── STATE.a2ml # Project state, progress, blockers +│ │ ├── META.a2ml # Architecture decisions, governance +│ │ ├── ECOSYSTEM.a2ml # Ecosystem position, relationships +│ │ ├── AGENTIC.a2ml # AI agent interaction patterns +│ │ ├── NEUROSYM.a2ml # Neurosymbolic integration config +│ │ └── PLAYBOOK.a2ml # Operational runbook │ ├── bot_directives/ # Per-bot rules and constraints │ └── contractiles/ # Policy enforcement contracts │ ├── k9/ # Security levels (Kennel/Yard/Hunt) @@ -217,7 +218,7 @@ project/ * `Justfile` * `README.adoc` * `LICENSE` (MPL-2.0) -* `.machine_readable/STATE.a2ml` +* `.machine_readable/descriptiles/STATE.a2ml` * `.well-known/security.txt` * `.well-known/ai.txt` * `.well-known/humans.txt` diff --git a/docs/governance/MAINTENANCE-CHECKLIST.a2ml b/docs/governance/MAINTENANCE-CHECKLIST.a2ml index e8c11c0..203f3c5 100644 --- a/docs/governance/MAINTENANCE-CHECKLIST.a2ml +++ b/docs/governance/MAINTENANCE-CHECKLIST.a2ml @@ -2,7 +2,7 @@ # Cross-repo maintenance baseline (machine-readable canonical) [metadata] -name = "Cross-repo maintenance baseline" +name = "maintenance-checklist" version = "1.1.0" last-updated = "2026-02-24" scope = "cross-repo" diff --git a/docs/practice/AI-CONVENTIONS.adoc b/docs/practice/AI-CONVENTIONS.adoc index 4a6aba1..5df9c03 100644 --- a/docs/practice/AI-CONVENTIONS.adoc +++ b/docs/practice/AI-CONVENTIONS.adoc @@ -12,7 +12,7 @@ Per-tool config files (.cursorrules, .clinerules, etc.) reference this document. ## Session Startup 1. Read `0-AI-MANIFEST.a2ml` FIRST (mandatory gatekeeper). -2. Read `.machine_readable/STATE.a2ml` for current status and blockers. +2. Read `.machine_readable/descriptiles/STATE.a2ml` for current status and blockers. 3. Read `.machine_readable/anchors/ANCHOR.a2ml` for canonical authority boundaries. 4. Read `.machine_readable/policies/MAINTENANCE-AXES.a2ml` for maintenance/audit sequencing. 5. Read `.machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml` for baseline controls. @@ -80,7 +80,7 @@ Use `just` (Justfile) for all build, test, lint, and format tasks. - `0-AI-MANIFEST.a2ml` -- universal AI entry point - `.machine_readable/AGENTIC.a2ml` -- agent permissions and constraints -- `.machine_readable/STATE.a2ml` -- current project state +- `.machine_readable/descriptiles/STATE.a2ml` -- current project state - `.machine_readable/anchors/ANCHOR.a2ml` -- canonical authority and policy boundary - `.machine_readable/policies/MAINTENANCE-AXES.a2ml` -- canonical axis sequencing and audit requirements - `.machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml` -- baseline maintenance checklist policy diff --git a/scripts/validate-session-contracts.sh b/scripts/validate-session-contracts.sh new file mode 100644 index 0000000..54dd1cc --- /dev/null +++ b/scripts/validate-session-contracts.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: MPL-2.0 +# Validate the two session policies with their actual Nickel evaluator. +set -euo pipefail +command -v nickel >/dev/null || { + echo "nickel is required to validate .k9.ncl session policies" >&2 + exit 2 +} +if [[ "${1:-}" == --typecheck ]]; then + shift + [[ $# -gt 0 ]] || { echo 'Supply the instantiated Nickel or K9 files to typecheck' >&2; exit 2; } + for file in "$@"; do + IFS= read -r magic < "$file" + if [[ "$magic" == 'K9!' ]]; then + tail -n +2 "$file" | (cd -- "$(dirname -- "$file")" && nickel typecheck) + else + nickel typecheck "$file" + fi + echo "$file: Nickel typecheck passed (deployment not executed)" + done + exit 0 +fi +[[ $# -eq 0 ]] || { echo 'Usage: validate-session-contracts.sh [--typecheck FILE...]' >&2; exit 2; } +for file in coordination.k9.ncl session/custom-checks.k9.ncl; do + IFS= read -r magic < "$file" + if [[ "$magic" != 'K9!' ]]; then + echo "$file: missing K9! envelope" >&2 + exit 1 + fi + # K9! is a transport envelope, not a Nickel expression. These standalone + # records have no imports; evaluation also exercises their field contracts. + tail -n +2 "$file" | nickel export --format json >/dev/null + echo "$file: Nickel evaluation passed" +done diff --git a/session/README.adoc b/session/README.adoc index d14a6d7..29139e7 100644 --- a/session/README.adoc +++ b/session/README.adoc @@ -11,7 +11,7 @@ Authoritative protocols live in: This repo keeps only thin bindings: * `+dispatch.sh+` maps canonical commands to central protocol paths. -* `+custom-checks.k9+` defines repo-local policy checks. +* `+custom-checks.k9.ncl+` defines repo-local policy checks. * `+local-hooks.sh+` provides optional repo-specific hook behavior. === Canonical Commands diff --git a/session/custom-checks.k9 b/session/custom-checks.k9.ncl similarity index 79% rename from session/custom-checks.k9 rename to session/custom-checks.k9.ncl index 30ef897..6f6f36b 100644 --- a/session/custom-checks.k9 +++ b/session/custom-checks.k9.ncl @@ -5,22 +5,15 @@ K9! { pedigree = { schema_version = "1.0.0", - component_type = "session-policy", - security = { - leash = 'Kennel, - trust_level = "data-only", - allow_network = false, - allow_filesystem_write = false, - allow_subprocess = false, - }, metadata = { - name = "session-custom-checks", + name = "custom-session-checks", version = "0.1.0", - description = "Repository-local session state checks", + }, + security = { + leash = 'Kennel, }, }, - version = "0.1", checks = [ { id = "session-state-has-next-action", diff --git a/tests/e2e/template_instantiation_test.sh b/tests/e2e/template_instantiation_test.sh index cc0ccb8..e79f02a 100755 --- a/tests/e2e/template_instantiation_test.sh +++ b/tests/e2e/template_instantiation_test.sh @@ -234,8 +234,8 @@ done log_step "Verifying machine-readable metadata" METADATA_FILES=( - ".machine_readable/STATE.a2ml" - ".machine_readable/META.a2ml" + ".machine_readable/descriptiles/STATE.a2ml" + ".machine_readable/descriptiles/META.a2ml" ) for file in "${METADATA_FILES[@]}"; do diff --git a/tests/e2e.sh b/tests/templates/e2e.sh.template similarity index 96% rename from tests/e2e.sh rename to tests/templates/e2e.sh.template index 11143fc..2b55c8b 100755 --- a/tests/e2e.sh +++ b/tests/templates/e2e.sh.template @@ -8,8 +8,8 @@ # Customise this file for your project. Delete the examples that don't apply. # # Usage: -# bash tests/e2e.sh -# just e2e +# bash tests/templates/e2e.sh.template +# Enable the workflow template only after replacing the examples with real checks. # # Merge requirements (STANDING): All 6 test categories must pass before merge: # P2P, E2E (this file), aspect, execution, lifecycle, benchmarks @@ -17,7 +17,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +PROJECT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" PASS=0 FAIL=0 @@ -34,7 +34,7 @@ bold() { printf '\033[1m%s\033[0m\n' "$*"; } # check