Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(282): pre-commit secret-scanning defaults #35

feat(282): pre-commit secret-scanning defaults

feat(282): pre-commit secret-scanning defaults #35

Workflow file for this run

# =============================================================================
# tachi pytest matrix — init.sh substitution + source-pattern hardening suite
# =============================================================================
#
# Purpose: Run the F-248 substitution-surface suite AND the F-256 source-
# pattern-hardening suite (`tests/scripts/test_init_sh_*.py` +
# `tests/scripts/test_template_*.py`) on a 2-runner cross-platform matrix to
# catch bash-version regressions:
#
# - macos-latest ships bash 3.2.57 (Apple's bundled /bin/bash). This is
# the OLDEST supported runtime and the strictest gate for compatibility
# constraints in `.aod/scripts/bash/template-substitute.sh`,
# `.aod/scripts/bash/init-input.sh`, `.aod/scripts/bash/template-git.sh`,
# and `.aod/scripts/bash/template-config-load.sh` (NFR-001: bash 3.2.57+;
# no `mapfile`, no associative arrays, no `${var,,}`).
#
# - ubuntu-latest ships bash 5.x. This is the modern reference shell;
# a green ubuntu run on top of a green macOS run proves the test
# suite is portable, not bash-3.2-quirk-locked.
#
# The workflow:
# 1. Checks out the repo at the PR head SHA
# 2. Sets up Python 3.11 (matches `tachi-mmdc-preflight.yml` baseline;
# pytest is installed via `python -m pip install pytest pytest-timeout`)
# 3. Asserts `bash --version` to make the matrix gate visible in logs
# 4. Runs the F-248 init.sh suite + the F-256 template-* suite with
# `--timeout=1080` (per F-250 outer cap rationale; see header comment
# on the pytest step below)
# 5. Both matrix legs MUST pass green
#
# Path filter (NFR-005 alignment + scope discipline): the workflow ONLY
# fires when files in the F-248 + F-256 hardening surfaces change. Pure
# docs edits, ADR text, or unrelated agent-tier changes do NOT trigger
# this job. This mirrors the narrow-scope pattern of `tachi-mmdc-preflight.yml`
# and avoids burning CI minutes on edits that cannot affect substitution or
# config-loading behavior.
#
# Path-filter completeness pattern (F-250 lesson, reinforced by F-256):
# the `paths:` filter and the `pytest` invocation MUST be kept in lock-step.
# When adding a new test file or refactoring a new bash library file,
# update BOTH the `paths:` trigger list AND the `python -m pytest ...`
# command in the same commit. F-256 added 5 new test modules and a new
# canonical helper (`template-config-load.sh`); all are now wired through
# both paths and invocation below.
#
# References:
# - specs/248-substitution-surface-hardening/spec.md (FR-001..FR-011, NFR-001)
# - specs/248-substitution-surface-hardening/tasks.md (T039, T040)
# - specs/250-adversarial-unit-extraction-hotfix/spec.md (timeout philosophy
# + session-scoped fixture rationale)
# - specs/256-source-pattern-hardening/spec.md (FR-1..FR-9, NFR-1..NFR-6,
# SC-1..SC-15) — adds Sites A-D + Stream 4 watchdog + canonical KV-load
# primitive `aod_template_load_kv_file`
# - docs/architecture/02_ADRs/ADR-038-placeholder-substitution-strategy.md
# §Test Coverage (F-248)
# - docs/architecture/02_ADRs/ADR-040-config-file-parsing-hardening.md
# §Test Coverage (F-256)
# =============================================================================
name: tachi pytest
on:
pull_request:
paths:
- scripts/init.sh
- .aod/scripts/bash/init-input.sh
- .aod/scripts/bash/template-substitute.sh
- .aod/scripts/bash/template-validate.sh
- .aod/scripts/bash/template-git.sh
- .aod/scripts/bash/template-config-load.sh # F-256
- .aod/templates/constitution-clean.md
- .aod/templates/constitution-instructional.md
- .aod/template-manifest.txt
- stacks/*/defaults.env # F-256 — Site A whitelist surface
- tests/scripts/test_init_sh_substitution.py
- tests/scripts/test_init_sh_adversarial.py
- tests/scripts/test_init_sh_constitution.py
- tests/scripts/test_init_sh_self_delete.py
- tests/scripts/test_template_substitute_unit.py
- tests/scripts/test_init_input_unit.py
- tests/scripts/test_substitute_shim_canary.py
- tests/scripts/test_init_sh_defaults_env.py # F-256
- tests/scripts/test_template_config_load_unit.py # F-256
- tests/scripts/test_template_config_load_integration.py # F-256
- tests/scripts/test_template_git_clone_timeout.py # F-256
- tests/scripts/test_template_substitute_lint_no_eval.py # F-256
- tests/scripts/test_init_precommit_matrix.py # F-5 (282)
- tests/scripts/init_sh_helpers.py
- tests/scripts/conftest.py
- tests/fixtures/init-baseline-tree/**
- tests/fixtures/regenerate-baseline.sh
- tests/fixtures/regenerate-config-load-baseline.sh # F-256
- tests/fixtures/config-load/** # F-256
- .github/workflows/tachi-pytest.yml
permissions:
contents: read
jobs:
init-sh-suite:
name: pytest init.sh suite — ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install pytest + pytest-timeout + pyyaml
# Required by the suite + tests/scripts/conftest.py:
# - pytest: runner
# - pytest-timeout: per-test wall-clock cap (--timeout=300)
# - pyyaml: conftest.py imports `yaml` at module scope (cross-suite
# shared with BLP-01 + F-241 detection-agent attestation tests
# which load schemas/finding.yaml + .claude/agents/tachi/*.yml)
run: |
python -m pip install --upgrade pip
python -m pip install 'pytest>=8' 'pytest-timeout>=2' 'pyyaml>=6'
- name: Diagnostic — bash version (NFR-001 compatibility gate)
# Make the matrix runner's bash version visible in CI logs. macOS
# ships /bin/bash 3.2.57 (the strict gate); ubuntu ships /bin/bash
# 5.x (the modern reference). Both must pass the suite.
run: |
echo "uname: $(uname -a)"
echo "/bin/bash --version: $(/bin/bash --version | head -1)"
echo "default bash --version: $(bash --version | head -1)"
- name: Run F-248 + F-256 hardening pytest suite
# Direct invocation: `pytest` resolves to the venv-installed binary.
# `--timeout=1080` is the OUTER pytest per-test cap; the helper's
# subprocess `run_init_in_clone(timeout_sec=900)` is the INNER cap on
# a single init.sh invocation. macos-latest GitHub Actions runners
# are notoriously ~3-4× slower than dev machines for arm64 bash work
# (~140-175s on dev → ~560-700s cold-cache on macos-latest at the
# 4× worst-case multiplier). F-250 promoted `init_run` to a session-
# scoped fixture in conftest.py so the macos cold-cache cost is paid
# ONCE per session instead of once per module — the outer/inner
# timeouts give ~200s/180s slack on the worst observed scenario.
#
# The unit modules (test_template_substitute_unit, test_init_input_unit,
# test_substitute_shim_canary, test_template_config_load_unit) are
# sub-second per case. The integration modules (test_init_sh_*,
# test_template_config_load_integration, test_template_git_clone_timeout)
# take longer because they spawn `init.sh` subprocesses or hanging-
# upstream fixtures. All sit in the same pytest invocation so changes
# to either the substitution surface (F-248) or the source-pattern
# surface (F-256) trigger the full CI run.
#
# F-256 modules added (Wave 3 + Wave 4):
# test_init_sh_defaults_env.py — Site A — stacks/*/defaults.env
# test_template_config_load_unit.py — KV-parser primitive
# test_template_config_load_integration.py — full library round-trip
# test_template_git_clone_timeout.py — Stream 4 watchdog + AOD_FETCH_TIMEOUT
# test_template_substitute_lint_no_eval.py — eval-removal lint guard
run: |
python -m pytest \
tests/scripts/test_init_sh_substitution.py \
tests/scripts/test_init_sh_adversarial.py \
tests/scripts/test_init_sh_constitution.py \
tests/scripts/test_init_sh_self_delete.py \
tests/scripts/test_template_substitute_unit.py \
tests/scripts/test_init_input_unit.py \
tests/scripts/test_substitute_shim_canary.py \
tests/scripts/test_init_sh_defaults_env.py \
tests/scripts/test_template_config_load_unit.py \
tests/scripts/test_template_config_load_integration.py \
tests/scripts/test_template_git_clone_timeout.py \
tests/scripts/test_template_substitute_lint_no_eval.py \
tests/scripts/test_init_precommit_matrix.py \
-v --timeout=1080