OmniNode-ai

Checkpoint

Pipeline checkpoint management for resume, replay, and phase validation

OmniNode-ai 4 3 Updated 3mo ago

Resources

1
GitHub

Install

npx skillscat add omninode-ai/omniclaude/checkpoint

Install via the SkillsCat registry.

SKILL.md

Checkpoint

Overview

Checkpoints record the successful completion of each pipeline phase. They are written after a phase finishes (never during) and enable:

  • Resume: Restart a pipeline from a specific phase without re-running prior phases
  • Validation: Verify that prior phase outputs are structurally sound before skipping
  • Replay: Audit trail of pipeline execution across attempts
  • Idempotency: Append-only writes with monotonically increasing attempt numbers

Checkpoints are backed by the omnibase_infra checkpoint node infrastructure and managed through the checkpoint_manager.py CLI wrapper.

Announce at start: "I'm using the checkpoint skill to manage pipeline state."

Backing Status ()

Backed by (real, non-stub): omnibase_infra/src/omnibase_infra/nodes/node_checkpoint_effect/ (EFFECT — read/write/list handlers) and omnibase_infra/src/omnibase_infra/nodes/node_checkpoint_validate_compute/ (COMPUTE — validate handler), invoked in practice via plugins/onex/hooks/lib/checkpoint_manager.py (functional CLI wrapper, no stub markers).

The generated omniclaude shell node_skill_checkpoint_orchestrator (maturity: stub in its contract.yaml) is a Polly-passthrough that is NOT the real dispatch path for this skill — it exists only from the bulk generate_skill_node.py pass and is never actually invoked. skill_functional_audit's naive node_<skill_name> path match doesn't resolve to the real omnibase_infra node names above, which is why it (mis)flags this skill as a facade. Tracked cleanup: (repoint the registry / retire the dead shell).

Storage Layout

Checkpoints are stored as YAML files under the user's home directory:

$ONEX_STATE_DIR/checkpoints/{ticket_id}/{run_id}/phase_{N}_{name}_a{attempt}.yaml

Where:

  • {ticket_id} -- Linear ticket identifier (e.g., PROJ-1234)
  • {run_id} -- Pipeline run UUID
  • {N} -- Phase ordinal (1-4)
  • {name} -- Phase value string
  • {attempt} -- Monotonically increasing attempt counter

Example:

$ONEX_STATE_DIR/checkpoints/{ticket_id}/e3a1b2c4-d5f6-5a78-9bcd-ef1234567890/phase_1_implement_a1.yaml
$ONEX_STATE_DIR/checkpoints/{ticket_id}/e3a1b2c4-d5f6-5a78-9bcd-ef1234567890/phase_2_local_review_a1.yaml
$ONEX_STATE_DIR/checkpoints/{ticket_id}/e3a1b2c4-d5f6-5a78-9bcd-ef1234567890/phase_2_local_review_a2.yaml  # retry
$ONEX_STATE_DIR/checkpoints/{ticket_id}/e3a1b2c4-d5f6-5a78-9bcd-ef1234567890/phase_3_create_pr_a1.yaml

Note: Short run IDs (e.g., a1b2c3d4) are normalized to deterministic UUID v5 values
on disk via _normalize_run_id(). The same short ID always maps to the same full UUID.

Writes are append-only: existing checkpoint files are never modified or overwritten.

Checkpoint Contract

Each checkpoint YAML file contains these fields:

Field Type Description
schema_version string Forward-compatibility version (currently "1.0.0")
run_id UUID Pipeline run correlation ID
ticket_id string Linear ticket identifier
phase enum Pipeline phase that completed
timestamp_utc datetime UTC timestamp of phase completion (explicitly injected)
repo_commit_map dict[str, str] Mapping of repo name to commit SHA
artifact_paths tuple[str, ...] Relative paths of output artifacts
attempt_number int (>=1) Monotonically increasing attempt counter
phase_payload union Phase-specific payload (discriminated on phase field)

Phase Ordinals

Phase Ordinal Value
Implement 1 implement
Local Review 2 local_review
Create PR 3 create_pr
Ready for Merge 4 ready_for_merge

Per-Phase Payload Reference

implement

Field Type Description
phase literal "implement" Discriminator
branch_name string Git branch name created
commit_sha string (7-40 hex) HEAD commit SHA after implementation
files_changed tuple[str, ...] Relative paths of changed files

local_review

Field Type Description
phase literal "local_review" Discriminator
iteration_count int (>=1) Number of review-fix iterations
issue_fingerprints tuple[str, ...] Fingerprints of issues found and resolved
last_clean_sha string (7-40 hex) Commit SHA of the last clean state

create_pr

Field Type Description
phase literal "create_pr" Discriminator
pr_url string Full URL of the created PR
pr_number int (>=1) PR number on the remote
head_sha string (7-40 hex) HEAD SHA pushed to the remote

ready_for_merge

Field Type Description
phase literal "ready_for_merge" Discriminator
label_applied_at datetime UTC timestamp when the merge-ready label was applied

CLI Usage

All operations use checkpoint_manager.py located at ${CLAUDE_PLUGIN_ROOT}/hooks/lib/checkpoint_manager.py.

Write a Checkpoint

python ${CLAUDE_PLUGIN_ROOT}/hooks/lib/checkpoint_manager.py write \
  --ticket-id {ticket_id} \
  --run-id a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  --phase implement \
  --attempt 1 \
  --repo-commit-map '{"omniclaude": "a1b2c3d"}' \
  --artifact-paths '["src/foo.py", "tests/test_foo.py"]' \
  --payload '{"branch_name": "feat/{ticket_id}", "commit_sha": "a1b2c3d", "files_changed": ["src/foo.py"]}'

Output:

{
  "success": true,
  "checkpoint_path": "{ticket_id}/a1b2c3d4.../phase_1_implement_a1.yaml",
  "correlation_id": "..."
}

Read Latest Checkpoint

python ${CLAUDE_PLUGIN_ROOT}/hooks/lib/checkpoint_manager.py read \
  --ticket-id {ticket_id} \
  --run-id a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  --phase implement

Output:

{
  "success": true,
  "correlation_id": "...",
  "checkpoint": { ... }
}

Validate a Checkpoint

Reads the checkpoint and then performs structural validation (schema version, path normalization, commit SHA format, phase-payload agreement, timestamp sanity).

python ${CLAUDE_PLUGIN_ROOT}/hooks/lib/checkpoint_manager.py validate \
  --ticket-id {ticket_id} \
  --run-id a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  --phase implement

Output:

{
  "is_valid": true,
  "success": true,
  "errors": [],
  "warnings": [],
  "correlation_id": "...",
  "checkpoint": { ... }
}

List All Checkpoints

# All checkpoints for a ticket
python ${CLAUDE_PLUGIN_ROOT}/hooks/lib/checkpoint_manager.py list \
  --ticket-id {ticket_id}

# Scoped to a specific run
python ${CLAUDE_PLUGIN_ROOT}/hooks/lib/checkpoint_manager.py list \
  --ticket-id {ticket_id} \
  --run-id a1b2c3d4-e5f6-7890-abcd-ef1234567890

Output:

{
  "success": true,
  "count": 3,
  "checkpoints": [ ... ],
  "correlation_id": "..."
}

Integration with ticket-pipeline

The ticket-pipeline skill writes checkpoints after each phase completes and validates them during --skip-to resume. See plugins/onex/skills/ticket-pipeline/prompt.md for the integration details.

Error Handling

  • omnibase_infra not installed: CLI prints JSON error and exits with code 1
  • Invalid phase name: CLI prints JSON error with valid phase list
  • Checkpoint already exists: Handler raises error (increment attempt_number)
  • Path traversal: Handler rejects ticket IDs that escape the checkpoint root
  • Absolute artifact paths: Rejected by both CLI and handler validation
  • Corrupt YAML files: Skipped during list, reported during read

All checkpoint operations in the pipeline context are non-blocking -- write failures log a warning but do not stop the pipeline.

Cron-Closeout Checkpoint Protocol

The headless cron-closeout pattern (scripts/cron-closeout.sh) uses a separate, simpler
checkpoint file for cross-invocation state persistence. This is distinct from the per-ticket
pipeline checkpoints above.

Storage

$ONEX_STATE_DIR/pipeline_checkpoints/cron-closeout-state.yaml
$ONEX_STATE_DIR/pipeline_checkpoints/cron-closeout.lock

Checkpoint Schema

schema_version: "1.0.0"
pass_count: 5                          # Total completed passes
last_status: success                   # success | noop | failure | halt | unknown
last_run_at: 2026-03-28T22:00:00Z     # UTC timestamp of last completion
consecutive_failures: 0                # Reset to 0 on success/noop; +1 on failure/halt
dry_run: false                         # Whether last pass used --dry-run

Lock File

The lock file prevents concurrent cron invocations from overlapping. It contains:

pid: 12345
started_at: 2026-03-28T22:00:00Z

Lock timeout is 45 minutes (matching the autopilot cycle mutex). A new invocation
finding a lock older than 45 minutes treats it as stale and removes it.

Circuit Breaker

3 consecutive failures (status failure or halt) prevent further invocations.
To reset: edit consecutive_failures in the checkpoint file to 0, or delete the
checkpoint file entirely.

Relationship to Pipeline Checkpoints

Aspect Pipeline Checkpoints Cron-Closeout Checkpoint
Scope Per-ticket, per-phase Per-cron-loop, aggregate
Storage $ONEX_STATE_DIR/checkpoints/{ticket_id}/ $ONEX_STATE_DIR/pipeline_checkpoints/
Schema Full phase payloads Simple pass/fail counter
Writer checkpoint_manager.py cron-closeout.sh
Purpose Resume mid-pipeline Track cron loop health

See Also

  • ticket-pipeline skill (writes checkpoints after each phase)
  • local-review skill (writes checkpoints after each iteration when --checkpoint is provided)
  • omnibase_infra checkpoint nodes (infrastructure implementation)
  • scripts/cron-closeout.sh (headless cron pattern)