Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Summary
<!-- 1–3 sentences. What does this PR do and why? -->

## Related
<!-- Closes #123 / Ref tracebloc/other-repo#456 -->

## Type of change
- [ ] Feature
- [ ] Bug fix
- [ ] Tech-debt / refactor
- [ ] Docs
- [ ] Security / hardening
- [ ] Breaking change

## Test plan
<!-- What did you test? Commands run? Manual steps? -->

## Screenshots / recordings
<!-- For UI changes. Remove if N/A. -->

## Deployment notes
<!-- Env vars, migrations, rollout order, feature flags. Remove if N/A. -->

## Checklist
- [ ] Tests added / updated and passing locally
- [ ] Docs updated if behavior or config changed
- [ ] No secrets / credentials in the diff
- [ ] For security-sensitive paths: appropriate reviewer requested
90 changes: 90 additions & 0 deletions .github/workflows/template-rules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Template rules

# Runs the D9 template rule checker. Until this existed, NOTHING executed
# `scripts/check_templates.py`: the only CI change #89 made was arming the
# shared reusable's `ruff` job, which lints changed `.py` files and says
# nothing about the templates. So every "enforced" in families.json, the
# templates README, CLAUDE.md and #89's own body meant "enforced if the author
# remembers to run it locally" -- a checker that is never invoked is
# indistinguishable from one that always passes (start-training#89, 5/10).
#
# `paths:` is deliberately ABSENT. A path filter here would be the same defect
# one level up: edit only `scripts/check_templates.py` and the job that
# validates it would not run.

on:
pull_request:
types: [opened, reopened, synchronize, ready_for_review]
push:
branches: [develop, staging, main]

concurrency:
group: template-rules-${{ github.workflow }}-${{ github.ref }}
# PR runs supersede each other; PUSH runs must not. Cancelling on push
# leaves the earlier commit with a cancelled run and therefore NO verdict,
# which reads the same as never having been checked.
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
contents: read

jobs:
d9-rules:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
# The SDK's `requires-python` excludes older interpreters, and pip
# answers that by SILENTLY BACKTRACKING to an ancient release rather
# than failing: measured, `pip install tracebloc` under 3.9 resolves
# to 0.8.1, whose `_SURVIVAL_FRAMEWORKS` happens to match the mirror
# -- so a release predating these templates "confirms" them. Pinning
# the interpreter is what makes the floor check below meaningful.
python-version: '3.11'

- name: Install the SDK for the mirror cross-check
# `--no-deps` plus the handful of light imports `tracebloc/__init__`
# needs. This deliberately does NOT pull torch: the checker only reads
# `tracebloc.training.plan._SURVIVAL_FRAMEWORKS`, so a ~20 MB install
# buys a real cross-check instead of the "SDK not importable, skipping"
# note that made rule 14b advisory everywhere it mattered.
run: |
set -euo pipefail
python -m pip install --quiet --upgrade pip
python -m pip install --quiet --no-deps tracebloc
# Derived by FOLLOWING the import chain on a clean 3.11 venv, one
# missing module at a time, not by guessing: tracebloc 1.0.7's
# `training.plan` needs exactly these six. The first version of this
# step omitted numpy and the job went red -- correctly, because
# strict mode refuses to pass a mirror it cannot verify. Note pandas
# is NOT here: pip warns that tracebloc requires it, but that is the
# declared dependency set, not what this import path touches.
python -m pip install --quiet numpy psutil requests rich termcolor tqdm
# Fail here, loudly, rather than letting the checker report a
# vaguer "not importable" one step later.
python - <<'PY'
import importlib.metadata as m
from tracebloc.training.plan import _SURVIVAL_FRAMEWORKS
print("tracebloc", m.version("tracebloc"),
sorted(getattr(f, "value", f) for f in _SURVIVAL_FRAMEWORKS))
PY

- name: Mutation harness — every rule seen to FAIL
# Runs before the checker on purpose: the checker passing tells you the
# tree is clean, the harness tells you the checker can still fail. A
# deleted rule leaves the checker green (measured: deleting rule 16
# still printed "OK -- all D9 rules hold") and only the harness catches
# it.
run: python3 scripts/check_templates_mutations.py

- name: D9 rule checker
# Runs from the repo root; the checker resolves its own paths.
# TRACEBLOC_CHECK_STRICT makes "cannot determine the SDK version" a
# FAILURE here rather than a printed note, because a skipped
# cross-check in the one place that gates is the whole defect.
env:
TRACEBLOC_CHECK_STRICT: '1'
run: python3 scripts/check_templates.py
146 changes: 146 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
xrays/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# ds store
.DS_Store/*

.idea
.DS_Store

Loading
Loading