Skip to content

v0.14.0 — Cross-platform content modularization (platform sidecars + os-region injection gating) #90

v0.14.0 — Cross-platform content modularization (platform sidecars + os-region injection gating)

v0.14.0 — Cross-platform content modularization (platform sidecars + os-region injection gating) #90

Workflow file for this run

# Security note: This workflow uses NO github.event.* inputs and NO ${{ ... }}
# interpolation in `run:` blocks. All dynamic values come from GitHub-provided
# safe env vars ($GITHUB_WORKSPACE) or hard-coded literals. No injection surface.
name: validate
on:
push:
branches: [main, dev]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
fast-tests:
name: Fast self-tests (${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 5
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
- name: Plugin self-consistency (validate-anchor)
run: bash scripts/validate-anchor.sh
- name: Manifest validation (validate-manifests)
run: bash scripts/validate-manifests.sh
- name: Manifest negative fixtures
run: bash scripts/validate-manifests.sh --fixtures tests/manifest-fixtures
# Windows arm runs the curated core subset first release (spec §9); expand once
# proven stable — a flaky gate is worse than none.
- name: Command frontmatter negative fixtures
if: runner.os != 'Windows'
run: bash scripts/check-allowed-tools.sh --fixtures tests/command-fixtures
# Glob, not an enumerated list: a hardcoded list silently omits newly added
# tests (it had already omitted post-tool-use-tidy-fidelity.sh once).
# </dev/null: a hook that reads stdin must not inherit the runner's.
- name: Hook contracts (every tests/hook-contracts/*.sh)
shell: bash
run: |
set -euo pipefail
for t in tests/hook-contracts/*.sh; do
echo "=== $t"
bash "$t" </dev/null
done
- name: POSIX compatibility
if: runner.os != 'Windows'
run: bash tests/posix-compat.sh
- name: Windows compatibility (static invariants, all platforms)
run: bash tests/windows-compat.sh
- name: E2E fixture structural checks
if: runner.os != 'Windows'
shell: bash
run: |
set -euo pipefail
FIXTURE_DIR=$(bash tests/e2e-cpp-fixture/bootstrap.sh)
echo "Fixture: $FIXTURE_DIR"
# Verify key files exist
for f in feature_list.json AGENTS.md init.sh PROJECT-TOC.md session-handoff.md progress.md .clang-format .clang-tidy CMakeLists.txt scripts/lint.sh scripts/sanitizer-build.sh; do
test -f "$FIXTURE_DIR/$f"
echo "OK $f present"
done
# Verify feature_list.json parses and validates
python3 -c "
import json, re, sys
with open('$FIXTURE_DIR/feature_list.json') as f:
data = json.load(f)
assert data.get('project'), 'missing project'
assert len(data.get('features', [])) == 3, 'expected 3 features'
for feat in data['features']:
for field in ['id', 'name', 'description', 'status', 'done_criteria']:
assert field in feat, f'missing {field} in {feat.get(\"id\")}'
assert re.match(r'^[a-z0-9][a-z0-9-]*$', feat['id']), f'bad id: {feat[\"id\"]}'
if feat['status'] == 'pass':
assert feat.get('evidence') is not None, f'{feat[\"id\"]} pass but evidence null'
print('OK feature_list.json valid')
"
- name: Context budget measurement
if: runner.os != 'Windows'
run: bash scripts/measure-context.sh
- name: Hook timing benchmark
if: runner.os != 'Windows'
run: bash tests/bench/hook-timing.sh
- name: cpp-detect — fixture coverage
shell: bash
run: |
set -euo pipefail
for fixture in cmake meson make bazel; do
echo "--- ${fixture}-fixture ---"
output=$(bash scripts/cpp-detect.sh --target "tests/cpp-detection/${fixture}-fixture")
echo "${output}" | python3 -m json.tool
EXPECTED_BS="${fixture}" \
python3 -c "
import json, sys, os
expected_bs = os.environ['EXPECTED_BS']
d = json.loads(sys.stdin.read())
assert d['is_cpp_project'] is True, f'{expected_bs}-fixture not detected as cpp project'
assert d['build_system'] == expected_bs, f'{expected_bs}-fixture wrong build_system: ' + d['build_system']
print(f'OK {expected_bs}-fixture: build_system={d[\"build_system\"]}')
" <<< "${output}"
done
- name: index-builder smoke test on temp repo
if: runner.os != 'Windows'
shell: bash
run: |
set -euo pipefail
tmp=$(mktemp -d)
cd "${tmp}"
git init -q
git config user.email test@example.com
git config user.name test
echo "// main.c - hello" > main.c
git add -A
git commit -qm init
node "${GITHUB_WORKSPACE}/scripts/index-builder.mjs" --target .
test -f PROJECT-TOC.md
grep -q 'main.c' PROJECT-TOC.md
grep -q 'generated-at-commit' PROJECT-TOC.md
echo "OK index-builder smoke pass"
# Glob for the same reason as the hook-contracts step: enumeration rots.
- name: Script unit tests (every tests/unit/*.sh)
shell: bash
run: |
set -euo pipefail
for t in tests/unit/*.sh; do
echo "=== $t"
bash "$t" </dev/null
done
- name: cpp-detect — negative fixture (non-C/C++ stays dormant)
shell: bash
run: |
set -euo pipefail
out=$(bash scripts/cpp-detect.sh --target tests/cpp-detection/non-cpp-fixture)
echo "${out}" | python3 -m json.tool
echo "${out}" | python3 -c "import json,sys; d=json.load(sys.stdin); assert d['is_cpp_project'] is False, 'non-cpp-fixture wrongly detected as cpp'; print('OK non-cpp-fixture: is_cpp_project=false')"
- name: Skill-triggering coverage (structural, no LLM)
if: runner.os != 'Windows'
run: bash tests/skill-triggering/check-coverage.sh
shellcheck:
name: ShellCheck (lint shell scripts)
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install shellcheck
run: sudo apt-get update && sudo apt-get install -y shellcheck
- name: Lint hooks + scripts + tests
shell: bash
run: |
set -uo pipefail
files=()
while IFS= read -r f; do files+=("$f"); done < <(find hooks -type f ! -name '*.json' ! -name '*.cmd'; find scripts tests -type f -name '*.sh'; find templates -type f -name '*.sh.tpl')
printf 'Linting %d files:\n' "${#files[@]}"; printf ' %s\n' "${files[@]}"
echo "== full findings, all levels (informational) =="
shellcheck --severity=style --exclude=SC1091 "${files[@]}" || true
echo "== gate: fail on warning-severity and above =="
shellcheck --severity=warning --exclude=SC1091 "${files[@]}"