Skip to main content

Post-Commit Quality Gate

warning

This page describes a proposed/retained post-commit automation design. Its named template, prompt, hook, and Ralph engine are not currently tracked in this repository. Do not assume it runs after commits.

Overview

The post-commit quality gate is a closed-loop automation that runs after every commit. It analyzes exactly what changed, determines what tests and docs are affected, implements the missing coverage, runs the new tests until they pass, and produces a clean summary.

The goal: developer commits code; the loop handles test coverage and documentation.

Template: prd-post-commit.template.json Prompt: PROMPT_post-commit.md Stories: 12 (PC00-PC11) Slash command: /post-commit-loop-bootstrap [commit-ref]

Story Breakdown

IDTitleDepends OnOutput
PC00Commit analysis: classify every changed file--.ralph/pc-analysis.md, .ralph/post-commit-state.json
PC01Test assessment: identify coverage gapsPC00.ralph/pc-test-plan.md
PC02Implement vitest unit/integration testsPC01New/updated test files
PC03Implement playwright e2e testsPC01New playwright test files
PC04Run all tests, iterate on failuresPC02, PC03.ralph/pc-test-results.md
PC05Bruno: assess and update API test collectionsPC01.ralph/pc-bruno-results.md
PC06Docs assessment: identify documentation gapsPC00.ralph/pc-docs-plan.md
PC07Extract source facts for documentationPC06.ralph/extractions/<topic>.md
PC08Write or update documentationPC07Updated doc files, .ralph/pc-docs-results.md
PC09Docs verification: lint, links, accuracyPC08.ralph/pc-docs-verification.md
PC10Final cross-check and commit-ready summaryPC04, PC05, PC09.ralph/pc-summary.md
PC11Self-improvement: update guardrails from failuresPC10.ralph/pc-prompt-improvements.md, updated .ralph/guardrails.md

Flow

PC01, PC02, PC03, PC04, and PC05 are the testing track. PC06 through PC09 are the documentation track. Both tracks run in parallel and converge at PC10. PC11 always runs last and feeds improvements back into the loop.

Change Classification (PC00)

PC00 reads the commit diff and classifies every changed file:

TypeMeaningTest ImpactDoc Impact
NEW_FEATURENew exported function, class, route, or componentUnit + integration + e2e gapsNew doc needed
CHANGED_BEHAVIORExisting API signature or behavior changedStale tests to fixStale doc to update
BUGFIXTargeted fix, no interface changeRegression test gapPossibly none
REFACTORInternal restructure, no observable changeLikely noneLikely none
CONFIG_CHANGEpackage.json, tsconfig, env, dockerLikely noneREADME may need update
TEST_CHANGETest files onlyn/an/a
DOC_CHANGEDocumentation files onlyn/an/a
CHOREBuild scripts, lock files, formattingLikely noneLikely none

Test Gap Categories (PC01)

Gap TypePriorityWhat It Means
STALE_TESTCriticalExisting test asserts wrong behavior after a change
REGRESSION_GAPHighBug was fixed but no test would catch a recurrence
INTEGRATION_GAPHighNew route/endpoint with no API test
E2E_GAPMediumUser flow affected with no playwright coverage
UNIT_GAPMediumNew function with no unit test
API_COLLECTION_GAPMediumChanged API endpoint not covered in the Bruno collection

STALE_TEST items are addressed first -- they actively give false confidence.

Test Execution (PC04)

PC04 runs all new and modified tests and iterates on failures:

  1. Runs npm run test:run (vitest) for unit/integration tests
  2. If browser E2E tests were added: runs the owning Playwright command such as npm run test:admin:e2e or npm run test:widget:e2e; root test:e2e is a Vitest integration-pattern command, not Playwright
  3. For each failure: diagnoses root cause -- is the test wrong or did the code introduce a regression?
  4. Fixes test assertions (if test is wrong) or fixes source code (if code introduced a regression)
  5. Re-runs until all newly added tests pass

PC04 is not complete until all newly added tests pass. Pre-existing failures are documented but do not block completion.

Docs Gap Categories (PC06)

Gap TypePriorityWhat It Means
BROKEN_LINKCriticalDoc references a file/function/route that was renamed or removed
STALE_DOCHighExisting doc describes old behavior
NEW_DOC_NEEDEDHighNew feature/route with no documentation
README_NEEDEDHighSignificant new feature not mentioned in README
INCOMPLETE_DOCMediumDoc exists but missing required sections

Documentation uses the extract-then-write pattern: source facts are extracted to .ralph/extractions/<topic>.md in PC07 before any doc is written in PC08. This prevents fabricated content.

Grace Modes

The loop degrades gracefully when components are absent:

Absent ComponentBehavior
No bruno/ collectionPC05 skips with a note -- no error
No tests/e2e/ directoryPC03 skips -- no playwright tests created
No docs directoryDoc stories skip gracefully
No running server for E2EPlaywright test files are written but execution is skipped

Final Summary (PC10)

PC10 cross-checks every item in pc-analysis.md is accounted for and produces .ralph/pc-summary.md with an explicit status:

StatusMeaning
CLEANAll items addressed, all new tests pass, no broken links
NEEDS_ATTENTIONOpen blocking issues remain (listed explicitly)

Deferred items (non-blocking) are also listed with reasons for the next iteration.

Quality Gates

  • PC00 drives scope for ALL stories -- never work outside what the commit touched
  • Every test assertion must reflect actual current behavior, not aspirational behavior
  • Never break existing passing tests
  • All newly added tests must pass before PC04 is marked complete
  • Use extract-then-write for all doc changes: read source, extract to .ralph/extractions/, then write doc
  • Dry-run mode is mandatory for any endpoint with real external side effects
  • Never fabricate documentation content -- defer if source cannot be found

Artifacts

FileWritten ByPurpose
.ralph/pc-analysis.mdPC00Itemized commit change log
.ralph/post-commit-state.jsonPC00, PC10Loop state, items, completion status
.ralph/pc-test-plan.mdPC01Prioritized test gap plan
.ralph/pc-test-results.mdPC04Test run before/after metrics
.ralph/pc-bruno-results.mdPC05Bruno changes or skip reason
.ralph/pc-docs-plan.mdPC06Prioritized doc gap plan
.ralph/extractions/<topic>.mdPC07Source extraction artifacts
.ralph/pc-docs-results.mdPC08Per-file doc change summary
.ralph/pc-docs-verification.mdPC09Lint and accuracy verification
.ralph/pc-summary.mdPC10Final commit-ready summary

Self-Improvement (PC11)

After every run, PC11 reads the run's errors.log and progress.md and feeds failures back into the loop:

  • Adds new Signs to .ralph/guardrails.md for any repeated failure patterns (e.g. "this API always returns 201 not 200", "this file is always renamed to X")
  • Proposes PROMPT fixes to .ralph/pc-prompt-improvements.md when the prompt gave bad guidance -- does NOT edit the PROMPT directly, as that requires human review
  • Notes loop design gaps in .ralph/pc-loop-design-notes.md when a commit type isn't handled well

Over many commits, the guardrails file accumulates project-specific knowledge that gets injected into every subsequent run, making the loop smarter and reducing retries.

PRD Isolation

Each run generates a run-specific PRD (prd-post-commit-<hash>.json) so multiple runs don't overwrite each other. The template (prd-post-commit.template.json) is never modified. prd-active.json is a convenience copy of the most recent run.

Clean up old run PRDs with:

git clean -f .agents/tasks/prd-post-commit-*.json

Git Hook

Install once to run the loop automatically after every commit:

# Submodule layout (Ralph_Loops repo at .agents/ralph/):
cp .agents/ralph/.agents/ralph/post-commit.hook.sh .git/hooks/post-commit
chmod +x .git/hooks/post-commit

# Standalone layout (loop engine directly at .agents/ralph/):
cp .agents/ralph/post-commit.hook.sh .git/hooks/post-commit
chmod +x .git/hooks/post-commit

The hook auto-detects which layout you have at runtime.

The hook runs Ralph in the background by default (RALPH_POST_COMMIT_ASYNC=1) so it never blocks your terminal. After committing you can monitor progress:

# Watch the log:
tail -f ../<repo>--ralph-<hash>/.ralph/post-commit-<hash>.log

# Check the summary when done:
cat ../<repo>--ralph-<hash>/.ralph/pc-summary.md

Disable temporarily without uninstalling:

RALPH_POST_COMMIT=0 git commit -m "..."

Worktree Isolation

By default the hook runs inside an isolated git worktree (../<repo>--ralph-<hash>/) rather than your main working tree. This means:

  • Generated tests and documentation never appear as uncommitted changes in your repo
  • Your in-progress work is untouched while Ralph runs
  • You review the output as a normal PR before it merges

What the hook does automatically

  1. Creates ../<repo>--ralph-<hash>/ via git worktree add from HEAD
  2. Copies .env* files into the worktree so the environment matches
  3. Runs npm install in the worktree
  4. Points RALPH_ROOT at the worktree so all loop artifacts and generated files land there
  5. Runs the loop asynchronously in the background

Reviewing and merging

When the loop finishes, the hook prints the exact PR command for your git host. Review the worktree and push:

cd ../<repo>--ralph-<hash>
git add -A
git commit -m "test/docs: post-commit quality gate for <hash>"
git push -u origin ralph/post-commit-<hash>

Then open a PR — the hook auto-detects your remote and prints the right command:

# GitHub:
gh pr create --base <your-branch> --title "test/docs: post-commit quality gate for <hash>"

Disabling worktree mode

To run the loop directly in the main repo (no worktree created):

RALPH_POST_COMMIT_WORKTREE=0 git commit -m "..."

Or set it permanently in your shell profile:

export RALPH_POST_COMMIT_WORKTREE=0

Configuration reference

VariableDefaultMeaning
RALPH_POST_COMMIT1Set to 0 to disable the hook entirely
RALPH_POST_COMMIT_ASYNC1Set to 0 to block the terminal until complete
RALPH_POST_COMMIT_WORKTREE1Set to 0 to run in-place (no worktree)
RALPH_CLAUDE_MODELsonnetClaude model to use

Run Command (Manual)

# Bootstrap (defaults to HEAD):
/post-commit-loop-bootstrap

# Bootstrap for a specific commit:
/post-commit-loop-bootstrap abc1234

# Then run Ralph autonomously:
PROMPT_BUILD=.agents/ralph/PROMPT_post-commit.md \
PRD_PATH=.agents/tasks/prd-active.json \
bash .agents/ralph/loop.sh

# One story at a time (for debugging):
MAX_ITERATIONS=1 \
PROMPT_BUILD=.agents/ralph/PROMPT_post-commit.md \
PRD_PATH=.agents/tasks/prd-active.json \
bash .agents/ralph/loop.sh