Skip to content

Guard Catalogue — Enforcement Reference

Guard Catalogue — Enforcement Reference

This is the authoritative reference for every enforcement mechanism in claude-forge. Each entry documents what is enforced, which layer enforces it, and whether it is deterministic.

Enforcement Layers

claude-forge uses four enforcement layers, listed from most to least reliable:

LayerMechanismDeterminismFailure mode
Go MCP handlerGuard functions in tools/guards.go called by handlers in tools/handlers.go. Return error (blocking) or string (warning).DeterministicIsError=true MCP response; state not mutated
Go engineDecision logic in orchestrator/engine.go. Controls phase transitions, auto-approve, retry limits, skip gates.DeterministicReturns specific action types; orchestrator must follow
Shell hookBash scripts in scripts/. Fire on tool calls via Claude Code hook system. Exit 2 = block.Deterministic (fail-open if jq missing)Exit 2 blocks the tool call; exit 0 allows
Prompt instructionText in SKILL.md or agent .md files. Followed by the LLM non-deterministically.Non-deterministicLLM may skip or misinterpret

Design principle: All critical invariants (data integrity, human approval gates, safety constraints) are enforced by code (layers 1–3). Prompt instructions (layer 4) are used only for orchestration protocol compliance where code enforcement is impractical.

Blocking Guards (prevent state mutation)

These guards return errors and halt progression. The pipeline cannot advance until the condition is satisfied.

IDInvariantLayerCode locationTrigger
3aArtifact file must exist before phase-completeMCP handlerguards.go:Guard3aArtifactExistsphase_complete for phases with required artifacts
3bReview file must exist before marking task review as passedMCP handlerguards.go:Guard3bReviewFileExiststask_update with reviewStatus=completed_pass
3cTasks must be initialized before phase-5 startsMCP handlerguards.go:Guard3cTasksNonEmptyphase_start for phase-5
3eCheckpoint requires awaiting_human status before completionMCP handlerguards.go:Guard3eCheckpointAwaitingHumanphase_complete for checkpoint-a, checkpoint-b
3gCheckpoint B must be done/skipped before task initializationMCP handlerguards.go:Guard3gCheckpointBDoneOrSkippedtask_init
3jPending revision must be cleared before checkpoint completionMCP handlerguards.go:Guard3jCheckpointRevisionPendingphase_complete for checkpoint-a, checkpoint-b
Init requires prior input validationMCP handlerguards.go:GuardInitValidatedinit with validated=false
Artifact content must pass validationMCP handlerpipeline_report_result.gopipeline_report_result for review phases
R1Source edits blocked during phase-1/2 (read-only)Shell hookpre-tool-hook.sh Rule 1Edit/Write tool targeting files outside workspace
R2Git commits blocked during parallel phase-5 executionShell hookpre-tool-hook.sh Rule 2Bash tool with git commit while parallel tasks active
R5Git checkout/switch to main/master blocked during active pipelineShell hookpre-tool-hook.sh Rule 5Bash tool with git checkout main or git switch master
Stop signal blocked during active pipelineShell hookstop-hook.shClaude Code stop when status not in completed, abandoned, awaiting_human

Non-blocking Warnings (alert but allow)

These checks inject warnings into the conversation but do not prevent the action.

IDCheckLayerCode locationTrigger
3dDuplicate phase-log entryMCP handlerguards.go:Warn3dPhaseLogDuplicatephase_log
3fMissing phase-log entry at phase completionMCP handlerguards.go:Warn3fPhaseLogMissingphase_complete for phases requiring logs
3hTask number not found in stateMCP handlerguards.go:Warn3hTaskNotFoundtask_update
3iPhase status not in_progress at completionMCP handlerguards.go:Warn3iPhaseNotInProgressphase_complete
Agent output too short (< 50 chars)Shell hookpost-agent-hook.shAgent tool return during active phase
Review agent output missing verdict keywordShell hookpost-agent-hook.shAgent tool return during phase-3b, phase-4b
Impl review output missing PASS/FAIL keywordShell hookpost-agent-hook.shAgent tool return during phase-6

Engine Decisions (deterministic branching)

The orchestrator engine (orchestrator/engine.go) makes all phase-transition decisions deterministically based on state. The LLM orchestrator receives an action to execute; it does not choose what to do next.

IDDecisionConditionBehaviorCode location
D14Phase skipPhase in skippedPhasesReturns done action with skip: prefix; orchestrator calls phase_completeengine.go top of NextAction
D20Auto-approve (checkpoint bypass)autoApprove == true AND verdict is APPROVE or APPROVE_WITH_NOTESSpawns next phase agent, bypassing checkpointengine.go phase-3b/4b handlers
D21Retry limit (2×)designRevisions >= 2 or taskRevisions >= 2 or implRetries >= 2Forces human checkpoint (approve or abandon)engine.go phase-3b/4b/6 handlers
D22Parallel task dispatchFirst pending task has executionMode == "parallel"Spawns all consecutive parallel tasks simultaneouslyengine.go phase-5 handler
D23Impl review verdict routingParsed verdict from review-N.mdFAIL → re-spawn implementer; PASS → next taskengine.go phase-6 handler
D24PR skipskipPr == trueReturns done action, bypasses PR creationengine.go pr-creation handler
D26Post-to-source dispatchsource_type from request.md frontmatterGitHub → gh command; Jira → checkpoint; text → doneengine.go post-to-source handler

Artifact Validation (deterministic content checks)

The validation/artifact.go package validates artifact content when pipeline_report_result is called. Validation failures block phase advancement.

PhaseRequired artifactContent rule
phase-1analysis.mdMust contain ## heading
phase-2investigation.mdMust contain ## heading
phase-3design.mdMust contain ## heading
phase-3breview-design.mdMust contain APPROVE, APPROVE_WITH_NOTES, or REVISE
phase-4tasks.mdMust contain ## Task heading
phase-4breview-tasks.mdMust contain APPROVE, APPROVE_WITH_NOTES, or REVISE
phase-6review-N.mdMust contain PASS, PASS_WITH_NOTES, or FAIL
phase-7comprehensive-review.mdMust be non-empty
final-summarysummary.mdMust exist

Findings markers ([CRITICAL], [MINOR]) are counted and accumulated into the pattern knowledge base for historical analysis. This is non-blocking.

Automated Side Effects (deterministic actions)

ActionLayerCode locationTrigger
Final commit: amend summary.md + state.json into last commit, then force-pushShell hook (v1) / Engine exec action (v2)post-bash-hook.sh (v1 legacy) / engine.go final-commit action (v2)After post-to-source phase completes; pipeline_report_result called first so state.json is in "completed" state when committed
Revision counter incrementMCP handlerpipeline_report_result.goREVISE verdict in review phases
Pattern knowledge accumulationMCP handlerpipeline_report_result.goAny review phase completion with findings

Prompt-only Instructions (non-deterministic)

These behaviors are enforced only by LLM instructions. They cannot be guaranteed by code because they involve orchestration-level decisions that are impractical to express as state guards.

InstructionLocationWhy not code-enforced
Never pass isolation: "worktree" to Agent callsSKILL.mdClaude Code Agent tool parameter; no hook intercept point for Agent tool arguments
Always call pipeline_report_result after spawn_agent, exec, write_fileSKILL.mdOmission is a no-op (missing metric), not a state corruption; adding a timeout guard would add complexity disproportionate to risk
Wait for Dashboard or terminal response at checkpointsSKILL.mdpipeline_next_action absorbs the checkpoint state transition and long-polls for Dashboard approval (50 s). The LLM must re-call pipeline_next_action on still_waiting; the long-poll reduces iterations to minimize non-determinism
Parse skip: prefix from done action and call phase_completeSKILL.mdEngine returns the skip signal; if the orchestrator fails to parse it, pipeline_next_action returns the same skip signal again (self-correcting loop)

Dual-layer Enforcement Map

Some invariants are enforced at both the shell hook layer and the Go MCP handler layer. This provides defense-in-depth: the MCP handler fires first on MCP tool calls; the shell hook fires independently on Bash/Edit/Write tool calls.

InvariantShell hookMCP handler
Artifact must exist before phase advancementGuard 3a (phase_complete) + pipeline_report_result validation
Checkpoint requires human approvalGuard 3e (phase_complete requires awaiting_human)
Phase 1-2 read-onlyRule 1 (pre-tool-hook.sh)— (agents don't call MCP tools to edit files)
No parallel git commitsRule 2 (pre-tool-hook.sh)— (git commits go through Bash tool, not MCP)
No checkout to main/masterRule 5 (pre-tool-hook.sh)— (branch operations go through Bash tool)
Review verdict extractionShell warning (post-agent-hook.sh)Artifact content validation (validation/artifact.go)

Fail-open Guarantees

All shell hooks are fail-open: if jq is not installed or state.json cannot be read, the hook exits 0 (allow). This ensures the plugin never blocks legitimate non-pipeline work.

bash
# Every hook starts with this pattern:
command -v jq >/dev/null 2>&1 || exit 0

Released under the MIT License.