Skip to content

Human Gate Workflow

A human gate is a story in your sprint plan where PACE deliberately pauses and waits for you to review before advancing. When PACE reaches a story with human_gate: true, it runs the full pipeline — PRIME, FORGE, GATE, SENTINEL, CONDUIT, and SCRIBE — and then stops. It does not automatically advance to the next story.

This gives you a scheduled review point where you can:

  • Assess sprint progress before committing to the next phase
  • Review SENTINEL and CONDUIT advisory accumulations
  • Adjust the remaining plan based on what was actually built
  • Perform a stakeholder demo or sign-off

Configuring a human gate story

Add human_gate: true to any story in plan.yaml:

plan.yaml
stories:
- id: story-7
title: "Mid-sprint review and advisory clearance"
status: pending
human_gate: true
acceptance_criteria:
- "All open SENTINEL advisories resolved or escalated with written justification"
- "All open CONDUIT advisories resolved or escalated"
- "pytest -q exits 0"

The human_gate: true flag is a post-pipeline pause. FORGE runs, GATE evaluates, SENTINEL and CONDUIT review — all as normal. The pause happens only after the story receives a SHIP decision. A HOLD on a human gate story is handled exactly like any other HOLD (see What to Do When PACE Issues a HOLD).


What happens when PACE reaches a human gate

When a human gate story ships:

  1. PACE invokes SCRIBE to refresh the context documents (see Context in the review PR for details)
  2. PACE writes .pace/day-N/review-pr.md (or opens a real PR if platform.ci: github)
  3. PACE sets a PACE_PAUSED=true flag — a GitHub Actions variable, or a local .pace/paused file
  4. The orchestrator exits with status 0 — the story shipped; PACE is waiting, not failing
  5. Subsequent cron runs are skipped while PACE_PAUSED=true is set
  6. A notification is sent if alerts: is configured with a human_gate_reached event rule

Context in the review PR (GitHub)

Before opening the review PR, PACE invokes SCRIBE to refresh the context documents. The refreshed engineering.md, security.md, devops.md, and product.md appear in the review PR diff — giving reviewers an accurate snapshot of the codebase state at the gate point.

The PR body includes a ## Context section:

## Context
Context documents refreshed before this review:
- engineering.md (triggered by: src/auth.py, src/models/user.py)
- security.md (triggered by: src/auth.py)
Refresh cost: ~$0.03

If the context refresh fails, PACE still opens the PR. The ## Context section will contain a warning and the existing (pre-refresh) context documents will be used for Day N+1. You can trigger a manual refresh before resuming: python pace/orchestrator.py --refresh-context.


The terminal output will look like this:

[PACE] story-7 shipped.
[PACE] Human gate reached. Setting PACE_PAUSED=true.
[PACE] Review the sprint before advancing: see .pace/day-7/ artifacts.
[PACE] To resume: unset PACE_PAUSED or run with --resume.

What to review on a human gate day

Work through these in order. They are arranged from highest signal to lowest effort.

1. PROGRESS.md

Terminal window
cat PROGRESS.md

PROGRESS.md shows per-story actual cost vs estimate, retry count, and running sprint total. Look for:

  • Stories with a high retry count — may indicate poorly scoped acceptance criteria
  • Stories where actual cost far exceeded the estimate — may indicate scope creep or an overly large story
  • Total sprint cost vs the Day 0 projection

2. The advisory backlog

Terminal window
cat .pace/advisory_backlog.yaml

This lists every advisory finding from SENTINEL and CONDUIT that has accumulated but has not yet been resolved. On a clearance story (a human gate story with clearance acceptance criteria), FORGE is expected to work through this backlog. Review it before resuming to confirm clearance actually happened.

3. The artifact files for each completed story

Terminal window
ls .pace/day-*/

For the human gate story specifically:

Terminal window
cat .pace/day-7/gate-report.yaml
cat .pace/day-7/sentinel-report.yaml
cat .pace/day-7/conduit-report.yaml

Focus on:

  • SENTINEL advisory findings — non-blocking items that accumulated and are not yet fixed
  • CONDUIT advisory findings — CI/CD issues flagged but not blocking
  • Any PARTIAL verdicts in gate-report.yaml — these map to out_of_scope entries and will carry forward

4. The code that was built

Review the git log since the sprint started:

Terminal window
git log --oneline sprint-start-tag..HEAD

Or review the PRs opened by PACE if platform.ci: github. Confirm that what was built matches what the sprint plan intended.

5. The remaining plan

Open plan.yaml and review all stories with status: pending. Ask:

  • Are the remaining acceptance criteria still correct given what was actually built?
  • Have any requirements changed since the sprint started?
  • Is any story now clearly too large given how long completed stories took?

Making adjustments before resuming

You can edit plan.yaml freely before resuming. Common adjustments:

Add acceptance criteria to upcoming stories based on what you learned from completed ones:

- id: story-8
title: "User profile endpoint"
status: pending
acceptance_criteria:
- "GET /users/:id returns 200 with profile JSON"
- "Returns 404 for unknown user id" # added after story-7 review
- "pytest -q exits 0"

Add out_of_scope items to reflect decisions made during review:

- id: story-8
title: "User profile endpoint"
status: pending
out_of_scope:
- "Avatar upload — deferred to story-12"
acceptance_criteria:
- "GET /users/:id returns 200 with profile JSON"
- "pytest -q exits 0"

Add a new story to address an issue found during review — insert it with the next available id and status: pending. PACE runs stories in list order.


Resuming after a human gate

GitHub Actions

Go to Settings → Secrets and variables → Actions → Variables and either delete the PACE_PAUSED variable or set its value to false. The next scheduled cron trigger will pick up the next pending story.

Alternatively, manually dispatch the workflow from the GitHub Actions UI. Manual triggers bypass the paused check.

Local or other platforms

Terminal window
# Remove the paused flag file
rm .pace/paused
# Run the next story manually (replace 8 with the next story's day number)
python pace/orchestrator.py --day 8

Or use --resume, which automatically advances to the next status: pending story without requiring you to know its day number:

Terminal window
python pace/orchestrator.py --resume

Human gate checklist

Complete all of these before resuming:

  • Reviewed PROGRESS.md — sprint cost is within budget
  • Reviewed .pace/advisory_backlog.yaml — all advisories are cleared or escalated with written justification
  • Reviewed SENTINEL reports for each completed story — no unaddressed FAIL-level findings
  • Reviewed CONDUIT reports — CI configuration is sound
  • Reviewed the git diff or PRs — the code matches what the sprint plan intended
  • Adjusted remaining plan.yaml stories if scope has changed
  • Stakeholder sign-off obtained (if required by your process)
  • PACE_PAUSED variable deleted or set to false (GitHub), or .pace/paused file removed (local)