What
A reusable GitHub Action (ChelseaKR/exitdrill/action@<sha>) and a pre-commit hook definition that run exitdrill validate and exitdrill drill over committed synthetic fixtures in another repository, write the receipt as a workflow artifact, and can compare it to a committed reference receipt with --fail-on-loss-signal-increase. Results are also emitted as JUnit XML (one test case per dimension, status as the outcome, limitations as system-out) so any CI reads them, plus a summary in the job's step summary. Data-mode is hard-wired to synthetic: the action refuses to run unless the fixture directory carries the data_mode: synthetic_only marker validate-exercise already understands.
Why it matters
ExitDrill is a verifier with exit codes and replayable receipts — the shape CI wants — but today only its own repo runs it. A team maintaining a normalizer for their own export contract (outside this repo, as ADR 0001 intends) has no way to gate a regression in structural loss on every commit. The action is packaging over existing commands: no connector, no evidence family, no data category, so it is inside the freeze; the synthetic-only marker keeps the data-governance gate intact by construction.
Scope
action.yml (composite; pinned uv; inputs: baseline, export, attachment-root, reference-receipt, fail-on-loss-signal-increase), documented in docs/CI-USAGE.md.
--format junit on drill and compare (and --out for it), with a committed schema/fixture.
.pre-commit-hooks.yaml exposing exitdrill-validate.
- The action's own CI job runs it against
examples/synthetic-crm* and asserts the documented exit codes.
Out of scope
- Running any normalizer or canary lab; SARIF (there is no location-based finding to map); hosted dashboards.
Done when
- A workflow using the action on the clean fixture is green; on the lossy fixture with a clean reference it fails with exit 3 and a JUnit file marking the changed dimensions failed.
- Removing the synthetic-only marker makes the action stop before invoking
drill, with the reason in the summary.
- JUnit output contains no record values (disclosure gate) and validates against the JUnit schema.
- The pre-commit hook rejects a malformed baseline in under a second.
Pointers
src/exitdrill/cli.py (exit codes 0/2/3), src/exitdrill/exercise.py (data_mode marker), Makefile (demo-compare-policy), .github/workflows/ci.yml
docs/decisions/0002-synthetic-exercise-preflight.md, docs/DATA-GOVERNANCE.md
Proposed with AI assistance.
What
A reusable GitHub Action (
ChelseaKR/exitdrill/action@<sha>) and a pre-commit hook definition that runexitdrill validateandexitdrill drillover committed synthetic fixtures in another repository, write the receipt as a workflow artifact, and can compare it to a committed reference receipt with--fail-on-loss-signal-increase. Results are also emitted as JUnit XML (one test case per dimension, status as the outcome, limitations as system-out) so any CI reads them, plus a summary in the job's step summary. Data-mode is hard-wired to synthetic: the action refuses to run unless the fixture directory carries thedata_mode: synthetic_onlymarkervalidate-exercisealready understands.Why it matters
ExitDrill is a verifier with exit codes and replayable receipts — the shape CI wants — but today only its own repo runs it. A team maintaining a normalizer for their own export contract (outside this repo, as ADR 0001 intends) has no way to gate a regression in structural loss on every commit. The action is packaging over existing commands: no connector, no evidence family, no data category, so it is inside the freeze; the synthetic-only marker keeps the data-governance gate intact by construction.
Scope
action.yml(composite; pinneduv; inputs: baseline, export, attachment-root, reference-receipt, fail-on-loss-signal-increase), documented indocs/CI-USAGE.md.--format junitondrillandcompare(and--outfor it), with a committed schema/fixture..pre-commit-hooks.yamlexposingexitdrill-validate.examples/synthetic-crm*and asserts the documented exit codes.Out of scope
Done when
drill, with the reason in the summary.Pointers
src/exitdrill/cli.py(exit codes 0/2/3),src/exitdrill/exercise.py(data_modemarker),Makefile(demo-compare-policy),.github/workflows/ci.ymldocs/decisions/0002-synthetic-exercise-preflight.md,docs/DATA-GOVERNANCE.mdProposed with AI assistance.