Skip to main content
comet-guard.sh is the enforcement layer for Comet’s phase transitions. Before advancing from one phase to the next, it checks that all exit conditions are met — such as tasks being completed, verification reports existing, and branch status being handled. When a check fails, guard outputs a BLOCKED message with per-check [FAIL] lines and actionable Next: suggestions rather than silently blocking progress.

Usage

"$COMET_BASH" "$COMET_GUARD" <change-name> <phase> [--apply]
Arguments:
ArgumentDescription
<change-name>The name of the active change (alphanumeric, hyphens, underscores)
<phase>The current phase to validate exit conditions for
--applyAutomatically update .comet.yaml when all checks pass
Valid phases: open, design, build, verify, archive

What Guard Checks by Phase

Guard runs a different set of checks depending on the current phase. All checks must pass before --apply writes any state.
CheckCondition
proposal.mdFile exists and is non-empty
design.mdFile exists and is non-empty
tasks.mdFile exists and is non-empty
Task listtasks.md contains at least one task entry
When all checks pass with --apply, guard calls comet-state.sh transition <name> open-complete, which advances phase from open to design (full workflow) or directly to build (hotfix/tweak).
CheckCondition
proposal.mdFile exists and is non-empty
design.mdFile exists and is non-empty
tasks.mdFile exists and is non-empty
handoff_contextPoints to a non-empty file in .comet/handoff/
handoff_hashValid 64-character hex SHA256, matches current source material
Handoff markdowndesign-context.md exists alongside design-context.json
Handoff traceabilityMarkdown contains Generated-by, Mode, per-file Source: and SHA256: markers
Design Doc (if set)File exists, frontmatter links current change (comet_change), declares role: technical-design and canonical_spec: openspec
When all checks pass with --apply, guard calls comet-state.sh transition <name> design-complete, setting phase: build.
CheckCondition
isolationSet to branch or worktree
build_modeSet to subagent-driven-development, executing-plans, or direct
build_mode authorizationdirect is only allowed for hotfix/tweak workflows, or when direct_override: true is set
tasks.mdAll tasks marked [x]; no remaining [ ] tasks
proposal.mdFile exists and is non-empty
Build commandIf build_command is configured, it must exit 0
When all checks pass with --apply, guard calls comet-state.sh transition <name> build-complete, setting phase: verify, verify_result: pending, verification_report: null, and branch_status: pending.
CheckCondition
tasks.mdAll tasks marked [x]
Verify commandIf verify_command is configured, it must exit 0; otherwise falls back to build_command
verification_reportSet and points to an existing file
branch_statusEqual to handled
When all checks pass with --apply, guard calls comet-state.sh transition <name> verify-pass, setting verify_result: pass, phase: archive, and verified_at.
CheckCondition
archivedEqual to true
proposal.mdFile exists and is non-empty
tasks.mdAll tasks marked [x]
The archive phase is a read-only completeness verification. --apply has no effect when the phase is archive — no state transition is triggered.

The —apply Flag

Without --apply, guard exits with code 0 (all pass) or 1 (blocked) and prints results — but makes no changes to .comet.yaml. With --apply, guard delegates the state update to comet-state.sh transition internally after all checks pass:
"$COMET_BASH" "$COMET_GUARD" my-feature build --apply
# If all conditions pass:
# → runs task, isolation, build_mode, and build checks
# → calls: comet-state.sh transition my-feature build-complete
# → .comet.yaml updated: phase=verify, verify_result=pending
If any check fails, --apply has no effect — guard exits 1 and the state file is not modified.

Blocked Output

When validation fails, guard outputs BLOCKED with per-check [PASS]/[FAIL] results and Next: suggestions for each failing check. Example for a blocked build phase:
=== Guard: build → verify ===
  [PASS] isolation selected
  [PASS] build_mode selected
  [PASS] build_mode allowed for workflow
  [FAIL] tasks.md all tasks checked
    Unfinished tasks:
    42: - [ ] Add unit tests for auth module
    Next: complete or explicitly remove unfinished tasks, then mark tasks.md with '- [x]'.
  [PASS] proposal.md exists
  [FAIL] Build passes

BLOCKED — fix failing checks before proceeding to next phase
Each [FAIL] line includes the specific condition that failed and a concrete Next: action to resolve it.

Project Build and Verify Commands

If .comet.yaml has a build_command or verify_command field, guard runs it as part of the phase check:
  • build phase: runs build_command if configured; otherwise auto-detects package.json, pom.xml, or Cargo.toml
  • verify phase: runs verify_command if configured; falls back to build_command or the same auto-detection
Commands are run via "$COMET_BASH" -lc "<command>" and their output is printed if they fail. Set COMET_SKIP_BUILD=1 to bypass build/verify command execution during testing.
# In openspec/changes/my-feature/.comet.yaml or project-root .comet.yaml
build_command: npm run build
verify_command: npm test

Schema Validation

Before any phase checks run, guard calls comet-yaml-validate.sh to validate the .comet.yaml schema. If validation fails, guard exits immediately with a fatal error — phase checks are not run.